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.
%a function to read the image matrix M and plot the centroids of each plot
%on the image
centroiddata = centroid_image(H);
%compares the Mth image in 3D image matrix A to Nth in B
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.
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.
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).
A MATLAB function 'gsbeam.m' was written to replicate the function:
(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)
%Imports array of beam characterization measurements. Structure of M is
% [z, x, I, a] where z is the displacement of the beam blockage along
% the optical axis, x is the coordinate of razor edge, I is the measured
% output of the photodetector and a is the ambient light level
%and guess is an estimate of the parameters [Amplitude x0 width] for the
%Output Structure [z A x0 w residual_2norm]
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.
display(['Image Number ' num2str(n)])
%Imports mainoutbase.raw generated by python framesumexport2 and outputs
%Nth image matrix I
mainout=['/opt/EDTpdv/' mainoutbase '.raw'];
%open main output array
fid = fopen(mainout,'r');
arr = fread(fid,1024*1024,'float');
maintxt=['/opt/EDTpdv/' mainoutbase '.txt'];
str=strrep(str,'Camera Temperature on Digitizer Board:','');
str=strrep(str,'Camera Temperature on Sensor Board:','');
#Number of loops LoopN over which to sum SumN images of dim num_H by num_W
num_H = 1024
num_W = 1024
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.
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:
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.
xlabel('Stage Translation (mm)')
ylabel('Photodetector Output (V)')
text(0.8,0.2,['A = ' num2str(x(1))],'FontSize',12,'Interpreter','none','Units','normalized');
text(0.8,0.15,['x0 = ' num2str(x(2))],'FontSize',12,'Interpreter','none','Units','normalized');
text(0.8,0.1,['w = ' num2str(x(3))],'FontSize',12,'Interpreter','none','Units','normalized');
function result = gauss_beam1D(x0, xdata)
% x0(1) = offset
% x0(2) = amplitude
% x0(3) = x centroid location
% x0(4) = x width
result = x0(1) + x0(2).*exp(-2.0.*( ...
((xdata - x0(3)).^2)/(x0(4).^2)));
function [x y wx wy]=autogaussfit1(imgname,guess,imgdetails)
%guess = [offset amplitude centroidlocation width]
%imgdetails = [HWSrulerlocation exp.time]
%output vectors same format as guess
rulerz = imgdetails(1,1);
exposure = imgdetails(1,2);
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:
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.
function [X Y wX wY]=weekendbeamtime(basename,guess,N)
%fits 1D gaussian curve to N images in sequence of basename basefile
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.
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:
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:
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:
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),
(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)
Stephen and I added a new valve to Dewar's vacuum system. This valve allows the flow of atmospheric pressure into the system. We added 3 components to the system which were the valve, an adapter, and a T-intersection. After added these components, we continued to pump down only the highlighted yellow and green area with Dewar being closed off. The system pumped down to .1 mTorr until we decided to close off the pump. Once we close the pump off, we noticed the pressure began to rise. We took apart the system again and looked over the O-rings. We came across one ring with a sticky and clear material surround the rim and another ring with a fiber on it. We proceeded to clean and reassemble the system, but ran into this same issue. We tried to find where this leak was by squirting isopropyl around each ring and posibbly so a slower rise in pressure, but had no luck.
Afterwards, I checked both T-intersections individually and came across the same rise in pressure after closing off the valve for both tests. We suspect this may have been normal beforehand?
We continued by putting it all back together and taking data of the pumpdown.
In anticipation of the point absorber SURF project, I cleaned up the server rack and installed a new workstation today.
The workstation replaces the old one, whose hard drive had failed, with a more powerful machine. The hostname (tcs-ws), IP address (10.0.1.168), user name (controls), and standard password (written in the secret place) are all the same as before.
I moved the control consol from its old spot in the back corner of the lab to the bench beside the rack. This is a more convenient location because the Hartmann sensor realtime GUIs can now be easily seen from the optical tables. I mounted the HWS machine in the rack as well and reconnected the video multiplexer to all the machines.
I tested the Hartmann sensor Python software and confirmed it to be working. It required a minor bug fix to the realtime gradient field GUI code. It seems that since this script was last run, the input data file type has switched from pickled numpy to HDF5.
Aidan and I continued the lab clean-up today. There's still more to do, but we did fully clear the large optical table which formerly housed the 50 W CO2 laser. I moved the optical enclosure over from the small table to serve as the area for the point absorber experiment. Inside it I mounted the Hartmann sensor and a 532 nm Thorlabs LED source. The LED still needs collimating/focusing optics to be installed.
The VGA signal outputted by the multiplexer is too weak to drive two monitors. This has required video cables to be manually switched back and forth between the monitor mounted above the laser table and the desktop console.
Today I solved this problem by installing an amplifying (active) VGA splitter on the video output of the multiplexer. One output of the amplifier goes to the desktop monitor and the other to the laser table. We can now monitor the HWS realtime GUIs directly above the optical setup, with no cable swapping.
New gloves are ordered for the TCS and QIL labs. They arrive tomorrow (Friday).
Small/Medium size gloves need to be ordered in order to handle the optics carefully.
I've started building the NFS server for the QIL cymac. It's sitting on the workbench in the TCS lab next to the rack. Please don't move it or any of the parts behind it.
Despite some considerable time spent, I was not able to get the Omega SCR controllers working. The first unit definitely arrived damaged. None of its LED indicator lights ever functioned, despite those on the second controller working fine under the same setup. I tried swapping in the second controller, but it has no voltage output and a red LED is illuminated which, according to the manual, means "malfunction on trigger board" or "open SCR." Either way, the remedy is to "consult factory."
Since we have get moving with data collection, I installed a simple variable transformer (borrowed from the 40m) which steps up/down the AC voltage from 0-120 V with the turn of a knob. I soldered the leads of one of the heaters to a standard power cable which plugs directly into the transformer. I have tested it and confirmed it to work.
Ian and I moved some new hardware into the lab, shown in the below photos. It is from the shipment of loaned equipment recently returned by Whitman College.
The ZnSe lenses and windows were put in the CO2 drawer of the optics cabinet. The CO2 laser, AOM, and modulator drivers were left packaged in boxes underneath the large laser table.
I replaced the dead 24" monitor on the work bench, which is connected to the video multiplexer. Mike Pedraza was kind enough to bring us us a new one and take away the old one.
Today I made the first characterization measurements of the mocked-up adaptive wavefront control system planned for the signal recycling mirrors.
Inside the light-tight enclosure on the center table, I've assembled and aligned a 10.2 micron CO2 projector which provides a heating beam of up to 150 mW incident on an SRM-like test optic. A co-aligned 633 nm probe beam and Hartmann wavefront sensor are used to measure the resulting thermal lens. I've written and installed new software on the machine hws (10.0.1.167) for viewing the wavefront distortion in real time, as shown in the below screenshot. This viewer is launched from the terminal via the command $stream_gradient_CIT
There is also a second utility program for displaying the raw Hartmann sensor CCD image in real time, which is useful for aligning the probe beam. It is launched by the terminal command $stream_intensity_CIT
Lens Formation Time Scale
First, I made a time-resolved measurement of the thermal lens formation on the test optic at maximum heating beam power (150 mW). The lens appears to reach steady-state after 30 s of heating. When the heating beam is turned off, the lens decays on a very similar time scale.
Lens Strength v. Incident Heating Power
Second, I measured the thermal lens strength as a function of incident heating beam power, which I measured via a power meter placed directly in front of the test optic. Below is the approximate maximum optical path difference induced at several heating beam powers.
The above optical path differences are approximate and were read-off from the live display. I recorded Hartmann sensor frame data during all of these measurements and will be analyzing it further.
I installed the Maku Gigabit CCD camera driver software on the hws-ws machine. The camera viewer can be opened from the terminal (from any directory) with the command
and there is also a shortcut icon on the desktop. The camera is ocurrently on the subnet at 10.0.1.157 and is configured to get its IP via DHCP. We can assign it a static IP if we'd like to keep it on the network permanently.
I left the camera mounted on the CO2 laser table. It's connected and ready to use.
There were known to be huge (65%) heating beam power losses on the SRM AWC table, somewhere between the CO2 laser and the test optic. Today I profiled the setup with a power meter, looking for the dominant source of losses. It turned out to be a 10" focusing lens which had the incorrect coating for 10.2 microns. I swapped this lens with a known ZnSe 10" FL lens (Laser Research Optics LX-15A0-Z-ET6.0) and confirmed the power transmittance to be >99%, as spec'd. There is now ~310 mW maximum reaching the test optic, meaning that the table losses are now only 10%.
Using a single-axis micrometer stage I also made an occlusion measurement of the heating beam radius just in front of the test optic. I moved the 10" focusing lens back three inches away from the test optic to slightly enlarge the beam size. In this position, I measure a beam radius of 3.5+/-0.25 mm at 1.5" in front of the test optic (the closest I can place the power meter). The test optic is approximately 20" from the 10" FL lens, so the beam has gone through its waist and is again expanding approaching the test optic. I believe that at the test optic, the beam is very close to 4 mm.
There is an SDK for the camera with compiled examples. For a really quick image grab from the command line, use the following:
This will produce a BMP image. We should probably recompile the C code to produce a 16-bit TIFF image.
Aidan found a C demo code for acquiring a single image from the Mako CCD camera and saving it to disk (SynchronousGrab -- aliased on tcs-ws as makoGrab). I wrapped that inside my realtime HWS beam profiler code to create a realtime beam profiler for the Mako camera. The interface is identical to that for the HWS.
The Mako camera is running on the tcs-ws machine (10.0.1.168) and is launched from the console via the command
It is currently configured to write a raw image to the local frame archive every 5 seconds (it prints the write location in the console), which can be disabled by setting the "-d" flag.
I fixed a bug in how the raw Mako CCD camera images are being read into memory. The bmp files turn out to have a block memory layout that broke my in-place reader.
For archive purposes, attached is a write-up of all the HWS measurements I've made to date for the SRM CO2 projector mock-up.
I implemented an access point for LDAS to pull data from the TCS lab EPICS frame archive (fb4:/frames) via rsync. The setup is analogous to what is already running at the 40m for automated backups. Here are the implementation details in case we want to replicate this in other W. Bridge labs.
Two lab machines are needed, the frame builder machine (fb4; 10.0.1.156) and a second machine to handle the network interfacing with the outside world (tcs-ws; 10.0.1.168).
1. Set up an NFS mount on tcs-ws to remotely access the frame archive on fb4.
i. NFS server-side setup:
a. Install the required packages
controls@fb4:~$ sudo apt-get install rpcbind nfs-common nfs-kernel-server
b. Add the following line to the file /etc/exports
c. Restart the NFS-related services
controls@fb4:~$ sudo /etc/init.d/rpcbind restart
controls@fb4:~$ sudo /etc/init.d/nfs-common restart
controls@fb4:~$ sudo /etc/init.d/nfs-kernel-server restart
ii. NFS client-side setup:
controls@tcs-ws:~$ sudo apt-get install rpcbind nfs-common
b. Add the following line to the file /etc/fstab
10.0.1.156:/frames /fb4/frames nfs rw,nofail,sync,hard,intr 0 0
c. Create the directory for the mount point, then set ownership and permissions
controls@tcs-ws:~$ sudo mkdir /fb4/frames
controls@tcs-ws:~$ sudo chmod -R 775 /fb4
controls@tcs-ws:~$ sudo chown -R controls.root /fb4
c. Mount the new network drive
controls@tcs-ws:~$ sudo mount -a
2. Configure the rsync daemon on tcs-ws.
i. Create a new file named /etc/rsyncd.conf with the following content. These settings match those of the 40m setup.
max connections = 10
read only = yes
log file = /var/tmp/rsyncd.log
list = yes
uid = controls
gid = controls
use chroot = yes
strict modes = yes
pid file = /var/run/rsyncd.pid
comment = For LDAS access to TCS lab frame files
read only = yes
path = /fb4/frames
hosts allow = ldas-grid.ligo.caltech.edu,localhost
ii. Kill, then restart the rsync daemon. The daemon may not be already running.
controls@tcs-ws:~$ sudo kill `cat /var/run/rsyncd.pid`
controls@tcs-ws:~$ sudo rsync --daemon
3. Open a port through the gateway firewall for LDAS to access.
To do this, configure a new port forwarding on the linksys gateway router in the usual way (access the router settings via http://10.0.1.1 from the web browser of any subnet machine). For the TCS lab, the external-facing gateway port 2046 is forwarded to port 873 of tcs-ws (the standard rsync port).
Security is handled by the tcs-ws rsync daemon. Its config file allows outside access to only the hostname ldas-grid.ligo.caltech.edu, and that access is read-only and restricted to the /fb4/frames directory.
For testing purposes, another outside machine name can be temporarily appended to the "hosts allow" parameter of /etc/rsyncd.conf. For example, I appended my office desktop machine. From the outside machine, the connectability of the rsync server can be tested with:
user@outside-hostname:~$rsync -dt rsync://126.96.36.199:2046/ldasaccess
If successful, the command will return an output similar to
drwxr-xr-x 4096 2017/08/28 16:13:31 .
drwxr-xr-x 4096 2017/11/14 02:30:38 full
drwxr-xr-x 4096 2017/08/28 16:13:38 trend
showing the contents of the frame archive.
The 400 mW CO2 laser on the Hartmann table is currently configured for a measurement of its relative intensity noise. It is aligned to a TCS CO2P photodetector powered by a dual DC power supply beside the light enclosure. I got some data last night with the laser current dialed back for low output power (0.5-10 mW incident), but still need to analyze it. In the meantime please don't remove parts from the setup, as I may need to repeat the measurement with better power control.
Attached for reference is the RIN measurement from the initial data.
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.
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!...
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:
1) Comparing high temp (+10) with room temp
2) Comparing +9 with room temp
3) Comparing +8 with room temp
4) Comparing +7 with room temp
5) Comparing +6 with room temp
6) Comparing +5 with room temp
7) Comparing +4 with room temp
8) Comparing +3 with room temp
9) Comparing +2 with room temp
10) Comparing +1 with room temp
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.
Does this work?
Results of initial measurement of temperature sensitivity of Hartmann sensor
"Cold" images were taken at the following temperature:
| before | 32.3 | 45.3 | 37.0 |
| after | 32.4 | 45.6 | 37.3 |
"Hot" Images were taken at the following temperature:
| before | 36.5 | 48.8 | 40.4 |
| after | 36.4 | 48.8 | 40.4 |
"before" are the temperatures just before taking 5000 images, and "after" are
the temperatures just after taking the images. First column is the temperature
measured using the IR temp sensor pointed at the heat sink, the second column the
camera temperature, and the third column the sensor board temperature.
Temperature change produced by placing a "hat" over the top of the HP assembly and the top of the heatsinks.
Averaged images "cool" and "hot" were created using 200 frames (each).
Aberration parameter values are as follows:
Between cool and hot images (cool spots - hot spots)
Between cool images only
Between hot images only
Attached are two contour plots of the radial spot displacements, one between
cool and hot images, and the other between cool images only. The color
bars roughly indicate the values of maximum and minimum spot
1. anisotropy of the thermal expansion of the invar foil HP caused by the rolling
2. non-uniform clamping of the HP by the clamp plate
3. vertical thermal gradient produced by the temperature raising method
4. buckling of the HP due to slight damage (dent)
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.
I got the LTG CO2 laser to deliver 50.02W as measured by the Thorlabs 200W power head today. This required running the Glassman HV supply at full power (30.0kV, 31.1mA), tweaking the end grating and output coupler alignments, and cleaning the ZnSe Brewster windows on the laser tubes, and it only lasted a few seconds before dropping back to ~48W, but the laser delivered the specified power. In the factory it delivered 55W at the 10.6 micron line I am using now- I checked it with the CO2 laser spectrum analyzer- so there is more work to do.
Purchased from Lesker, for venting of IR Labs Cryostat:
- P/N C35103000 (KF10 Valve for up-to-air)
- P/N QF25XQF10 (KF25-KF10 Reducer)
- P/N QF25-100-T (KF25 Tee)
(to be connected in between the Chamber Tee and the Gate Valve)
Should be in next week!
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.
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):
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...
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.
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.
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
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.
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.
* EDT PCIe4 DV frame grabber: installation notes for linux system
Main issue I encountered was the fact that most of the shell scripts
did not run by simply entering them. It's bit strange because if you
do ls -al to view the file lists they are made executable. So it's
possible that others don't encounter the same kind of problems as I
However, if one executes the command "./linux.go", for example, and
receives the message saying
bash: ./linux.go: /bin/sh: bad interpreter: Permission denied
then one may follow the steps I took as below.
1. Make a folder to put the content of CD, for example:
2. Copy the content of the CD-ROM to the folder.
3. Go to the folder.
4. Change or check the mode of the following script files (using the
command chmod) to be executable (using "chmod a+x filename"):
~/fgdriver/linux/EDTpdv/installpdv (this one should already be
5. run ./linux.go and choose DV by clicking it.
I am assuming that the programming language Tcl is already installed
in the machine. CentOS 5.4 that I have installed came with Tcl. If Tcl
is not installed, I think that linux.go will run cli_startmenu.sh
instead (located in the same directory as linux.go). So make sure
cli_startmenu.sh is executable (see step 4).
6. Choose default installation directory and start installation
In my first attempt to install the files, the installation message
window hung after displaying many lines of "........". That was
because the file setup.sh was not made executable (see step 4). So I
made setup.sh executable, ran linux.go again, then I could see further
messages flowing through (basically compiling c source files). I'm not
sure whether others will enounter the exactly same problem though.
7. After the installation completes, go to the /opt/EDTpdv folder.
8. Final Step: Make edt_load and edt_unload executable. (See step 4)
Most of the other executables we need for running the frame
grabber/camera should already be executable at this point; but somehow
in my installation the above two files were not made executable. I
again do not know whether others will experience the same
problem. Since there are lots of executables generated when
installation completes, I advise that, whenever a certain command does
not run, one should check if that command file is executable or not.
Please let me know if you find any parts of the above confusing. I will
do my best to clarify.
Regarding the installation of EDT software, I overlooked a note from the install.pdf file.
The gist of it is that if the scripts do not run, then remount the CD-ROM by typing the
mount /mnt/cdrom -o remount,exec
which will then allow the scripts to be run. The directory /mnt/cdrom should be changed if
the cdrom is mounted somewhere else. (The note can be found in the page 1 of the file
Unfortunately I don't have linux installed at the moment so I cannot test this. My computer was
reinstalled with Windows XP, the previous CentOS system being wiped out. However if this works,
then there is probably no need to copy the files to the hard drive.
Attached is .m file of the custom function that I wrote and used to automatically detect peaks in a Hartmann image,
and calculate the centroid corrdinates of each of those peaks.
A simple example of its usage, provided that myimage is a two-dimensional image array obtained from the camera, is
radius = 10;
peak_positions = detect_peaks_uml(myimage,radius);
no_of_peaks = length(peak_positions);
centroids_array = zeros(no_of_peaks);
for k = 1:no_of_peaks
centroids_array(k,1) = peak_positions(k).WeightedCentroid(1);
centroids_array(k,2) = peak_positions(k).WeightedCentroid(2);
I chose my value of radius by looking at spots in a sample image and counting the number of pixels across a peak. It may be
more useful to automatically obtain a value for the radius. I may run some tests to see how different choices of radius
affect the centroid calculations.
I may also need to add some error checking and/or image validating codes, but so far I have not encountered any problems.
Please let me know if anyone needs more explanation!
function ctr = detect_peaks_uml(image,radius)
% Usage example:
% positions = detect_peaks_uml(myimage,10);
% total number of peaks detected: length(positions.WeightedCentroid)
% access the coordinates of the nth peak:
% positions(n).Weightedcentroid(1), positions(n).WeightedCentroid(2)
weighted_image = image .^ 2;
background = imopen(weighted_image,strel('disk',radius));
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 188.8.131.52 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_184.108.40.206.run to my home folder.
2. Ensure that the script is executable.
: chmod +x EDTpdv_lnx_220.127.116.11.run
3. Run the script.
: sudo ./EDTpdv_lnx_18.104.22.168.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
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.
I drew up one way we could set up the three available bake ovens in the TCS lab on the single oil pump.
If this looks feasible to others, we can move the ovens into the TCS lab. Duo and I will be occupied at KNI during Tuesday and Monday morning, so the usual lab cleanup time may not be the best. Perhaps Monday afternooon we can at least get the ovens out of the hallway and get one of them set up for baking.
My preference is to have tubes back towards the wall where possible. We might be able to drill a large diameter hole in the table top to accommodate them.
We have to get confirmation that the exhaust can be extracted - otherwise this whole thing is moot.
I have borrowed TCS's label maker in CTN for few days. If you need it, you can take it from the top of blue cabinets.
I lent your fancy Newport TrueRMS Supermeter with the thermocouple plugs on the top to the SURF student Jordon. He has it in the cryo lab or the EE workshop with one of the PSL lab temperature probes.
Borrowed thorlabs power meter on 21 Sep 2017. It is on the south table of the ATF lab.