Login| Sign Up| Help| Contact|

Patent Searching and Data


Title:
METHODS AND APPARATUS FOR IMAGE ANALYSIS
Document Type and Number:
WIPO Patent Application WO/2001/069534
Kind Code:
A2
Abstract:
Image analysis techniques may be provided. Location of objects in an image may be determined based on intensity characteristics of pixels in the image. Objects that have been located may be mapped to a source for the objects based for example, on a grid structure that may have been used to place the objects. Differential analysis of objects of two source materials in images may be determined based on aligned versions of the images. Filtering may be used to weigh pixel characteristics. Such object analysis techniques may have been encoded into a set of machine-executable instructions and stored on a machine-readable storage medium for use by equipment that is to perform the techniques.

Inventors:
TANNER CAMERON WAYNE
TEPESCH PATRICK DAVID
Application Number:
PCT/US2001/007711
Publication Date:
September 20, 2001
Filing Date:
March 09, 2001
Export Citation:
Click for automatic bibliography generation   Help
Assignee:
CORNING INC (US)
International Classes:
G06K9/36; G06K9/46; G06K9/66; G06T5/00; G06T7/00; (IPC1-7): G06T7/00
Domestic Patent References:
WO1986006835A11986-11-20
Foreign References:
US4075658A1978-02-21
Other References:
BRIGHT D S: "An object-finder for digital images based on multiple thresholds, connectivity, and internal structure" JOURNAL OF COMPUTER-ASSISTED MICROSCOPY, DEC. 1989, USA, vol. 1, no. 4, pages 307-329, XP008007968 ISSN: 1040-7286
Attorney, Agent or Firm:
Jackson, Robert J. c/o Fish & Neave 1251 Avenue of the Americas New York (NY, US)
VOSSIUS & PARTNER (Nr. 31) (Siebertstrasse 4 München, DE)
Download PDF:
Claims:
What is claimed is :
1. A method for automatically locating spots in an image based on intensities of points in the image, comprising : determining whether a current point in the image and two adjacent points have intensities that are approximately above a minimum threshold intensity ; and identifying whether part of a new spot is located at the current point based only on the intensities of the two adjacent points when the current point has an intensity that is approximately above the minimum threshold intensity.
2. The method of claim 1 wherein said determining comprises determining whether the current point and the two adjacent points have intensities that are approximately within a threshold range comprising the minimum threshold intensity and a maximum threshold intensity.
3. The method of claim 1 wherein said identifying comprises identifying based only on the two adjacent points when the current point is approximately within the threshold range.
4. The method of claim 1 further comprising providing a plurality of pixels that are representative of the points in the image.
5. The method of claim 4 wherein said determining and said identifying comprises using a current pixel that corresponds to the current point and two of the pixels that are adjacent to the current pixel which correspond to the two adjacent points in said determining and said identifying.
6. The method of claim 5 wherein, said determining comprises determining whether the current pixel and the two adjacent pixels have intensities that are approximately within a threshold range comprising the minimum threshold intensity and a maximum threshold intensity ; and said identifying comprises identifying when the current pixel has intensity that is approximately within the threshold range.
7. The method of claim 5 further comprising repeating said determining to evaluate the plurality of pixels by walking through the image pixelbypixel in lines of pixels.
8. A method of automatically locating spots in an image based on intensities of pixels in the image, comprising : determining whether a current pixel in the image and two pixels adjacent to the current pixel have intensities that are approximately within a threshold range ; identifying whether part of a new spot is located at the current pixel based only on the intensities of the two adjacent pixels when the current pixel has an intensity that is approximately within the threshold range ; and repeating said determining and said identifying to identify a high density array of spots.
9. The method of claim 8 wherein said identifying comprises identifying the current pixel to be part of a known spot when the two adjacent pixels have been identified to be part of that known spot.
10. The method of claim 8 wherein said identifying comprises identifying the current pixel to be part of a known spot when one of the two adjacent pixels has been identified to be part of the known spot and the intensity of the other one of the two adjacent pixels has been determined to be approximately outside the threshold range.
11. The method of claim 8 further comprising determining which ones of the other pixels are part of the new spot.
12. The method of claim 11 comprising determining whether any of the pixels that are determined to be part of the new spot are located at the edge of the image ; and rejecting the new spot in response to determining that the pixels in the new spot are located approximately at the edge of the image.
13. The method of claim 11 further comprising determining that a particular pixel in the image is part of the new spot based on that particular pixel being substantially enclosed by some of the pixels that have been determined to be part of the new spot.
14. The method of claim 8 further comprising identifying where another spot is located in the image based on determining an integrated intensity for a region that is centered on another one of the pixels.
15. A method for automatically locating spots in an image based on intensities of pixels in the image, comprising : searching for a first pixel that has an intensity that is approximately above a threshold intensity ; determining that a part of a new spot is located at the first pixel in response to said searching ; searching only nearest neighbors recursively starting from the first pixel to identify which ones of the pixels in the image are part of the new spot based on the threshold intensity ; and repeating said searching for a first pixel, said determining, and said searching to identify a high density array of spots in the image.
16. The method of claim 15 wherein said searching recursively comprises searching only nearest neighbors recursively starting from every pixel that is identified to be part of the new spot to identify which other ones of the pixels in the image are part of that new spot.
17. The method of claim 15 wherein said searching for the first pixel comprises searching serially pixelbypixel in lines of pixels.
18. The method of claim 15 wherein said searching recursively comprises searching recursively until substantially all of the pixels that are contiguous with the first pixel and that have intensities that are approximately above the threshold intensity are identified.
19. The method of claim 18 further comprising repeating said searching for a first pixel to locate another spot in response to identifying substantially all of the pixels that are part of the new spot.
20. A method for automatically locating spots in an image based on intensities of pixels in the image, comprising : searching serially for a first pixel that has an intensity that is approximately above a threshold intensity ; determining that part of a new spot is located at the first pixel in response to said searching ; and searching only nearest neighbors recursively starting from the first pixel to identify which ones of the pixels in the image are part of the new spot based on the threshold intensity.
21. The method of claim 20 wherein said searching serially and said searching only nearest neighbors includes searching each pixel in the image at most once.
22. The method of claim 20 further comprising determining whether one of the pixels that are identified to be part of the new spot are located approximately at an edge of the image.
23. The method of claim 20 further comprising determining that a particular pixel is part of the new spot based on that particular pixel being substantially enclosed by some of the pixels that are identified to be part of the new spot.
24. The method of claim 20 further comprising determining where another spot is located based on determining an integrated intensity for a region in the image that is centered on another one of the pixels.
25. A method for automatically locating spots in an image based on intensities of pixels in the image, comprising : determining an integrated intensity for each of a plurality of particularlyshaped regions that are each centered on a different one of a plurality of pixels in the image ; and identifying that a new spot is located in one of the regions based on the integrated intensity of that region in relation to the integrated intensities of the other regions.
26. The method of claim 25 wherein said determining comprises providing each of the regions to be approximately the size of a spot pitch for a plurality of spots that are in the image.
27. The method of claim 25 wherein said determining comprises masking each region before determining the integrated intensity.
28. The method of claim 27 wherein said masking comprises masking to sharpen spot characteristics.
29. The method of, claim 25 wherein said determining comprises determining which one of the regions has a highest integrated intensity in relation to the rest of the regions to identify which one of the regions includes a new spot.
30. A method for automatically locating spots in an image based on intensities of pixels in the image, comprising : determining an integrated intensity for a plurality of particularlyshaped regions that are each centered on a different ont of a plurality of pixels in the image; determining which one of the regions has a highest integrated intensity in relation to the rest of the regions to identify which one of the regions includes a new spot ; and setting any of the regions that overlap the region having the highest integrated intensity to have a lowest integrated intensity.
31. The method of claim 30 further comprising determining that a second spot is located in a next region having the next highest integrated intensity in relation to the other regions.
32. The method of claim 30 further comprising determining a, center point for the new spot based on a threshold intensity that is determined from the intensities of the pixels in the region in which the new spot was identified to be located.
33. The method of claim 30 wherein said determining which one comprises identifying that one of the regions includes the new spot based on characteristics of pixels that are in that region that are determined based on a threshold intensity.
34. The method of claim 30 further comprising determining a location for another spot based on a threshold intensity.
35. A method for relating a plurality of spots that have been placed on a slide to a grid comprising grid points that were used in placing the spots on the slide, comprising : providing an image that is representative of the slide ; determining where the spots are located in the image ; mapping the grid on to the image using a plurality of test locations on the image as origins for the grid to determine a best origin for the grid in relation to the spots ; and assigning each spot to one of the grid points in the grid based on evaluating which grid point is nearest to the location of that spot.
36. The method of claim 35 wherein said providing comprises generating the image using a plurality of pixels that are each representative of approximately one of a plurality of points on the slide based on an intensity of the point that each pixel represents.
37. The method of claim 36 wherein said mapping comprises selecting one of the test locations to be the best origin based on a total intensity for pixels that are approximately within a selected distance from each grid point.
38. The method of claim 36 further comprising selecting one of the test locations to be the best origin based on a total distance between every one of the grid points and the spot nearest to that grid point.
39. The method of claim 35 further comprising determining a positional relationship of the grid points to each other based a spot pitch, pin pitch, number of rows and columns of spots, and number of rows and columns of printer pins of a spot printer that was used to place the spots on the slide.
40. The method of claim 35 further comprising determining an actual spot pitch based on where spots are located in the image.
41. The method of claim 40 wherein said mapping further comprises adjusting the shape of the grid based on the actual spot pitch.
42. The method of claim 40 wherein said determining an actual spot pitch comprises determining a directional spot pitch vector by averaging vectors for pairs of nearest neighboring spots in approximately one direction.
43. The method of claim 40 wherein said determining an actual spot pitch comprises : sorting the spots based on where they are located in the image ; selecting a plurality of pairs of spots based on the sorted list ; and determining a spot pitch vector by averaging vectors for the selected pairs of spots.
44. A method for using intensities of pixels in a current image having a plurality of spots to filter further images comprising : identifying in a current image a plurality of similarlyshaped regions that each include one of the spots that each include a plurality of pixels ; and determining an average intensity profile for the regions based on averaging intensities for the pixels that are approximately in the same location in each of the identified regions ; and filtering intensities in further images using the average intensity profile.
45. The method of claim 44 wherein said identifying comprises centering each of the regions over the spot that is in that region.
46. The method of claim 44 wherein said filtering comprises filtering using the average intensity profile to weigh pixels in further images that are to be analyzed.
47. The method of claim 44 further comprising identifying spot locations in the further images based on the filtered intensities.
48. A method for analyzing a plurality of spots that are placed on a slide to test expressions of a plurality of source materials in the spots based on a plurality of images that are each differently representative of the slide, wherein locations of the spots in the images have been determined, comprising : determining an aligned image for each of a plurality of the images based on the locations of spots in one of the plurality of images in relation to the location of spots in each of the other images ; determining a composite image based on the aligned images ; determining which areas in the composite image comprises spots ; and analyzing areas in one of the aligned images for expressions of one of the source materials based on the areas that were determined to comprise spots in the composite image.
49. The method of claim 48 further comprising : providing for each of the plurality of the images a plurality of pixels that are each representative of a point on the slide being represented by that image ; and wherein said determining an aligned image, comprises aligning the pixels to form the aligned image for each slide.
50. The method of claim 49 wherein said aligning comprises applying a matrix transform on a pixelbypixel basis to determine the aligned image for each slide.
51. 5 1.
52. The method of claim 49 wherein said determining an aligned image comprises : selecting one of the images to be a reference image ; and aligning the other images to the selected reference image.
53. The method of claim 49 wherein said providing comprises : providing each of the plurality of pixels to have an intensity of the point which that pixel represents ; and said determining a composite image, comprises combining light intensities for pixels that are approximately in a same location in each of the aligned images.
54. The method of claim 49 wherein said determining which areas, comprises determining which areas based on a threshold intensity for the pixels in the composite image.
55. The method of claim 49 wherein said determining which areas, comprises determining which areas based on an integrated intensity for each of a plurality of regions in the composite image.
56. A method for automatically determining where spots in an image are located based on intensities of a plurality of pixels in the image, comprising : determining a threshold intensity for a particular image region based on intensities of a portion of the pixels in that region ; and determining whether one of the spots is at least partly located in the region based on the threshold intensity determined for that region.
57. The method of claim 55 wherein said determining a threshold intensity, comprises using the portion to be approximately a size of an average spot.
58. The method of claim 55 further comprising repeating for another region said determining a threshold intensity and said determining whether one of the spots to determine whether there are any spots in the other region.
59. The method of claim 57 wherein said repeating comprises selecting the other region based on a spot pitch for the spots in the slide and a current region.
60. The method of claim 55 wherein said determining whether one of the spots, comprises determining whether one of the spots is at least partly in the region based on characteristics of a group of the pixels in the particular region.
61. The method of claim 55 further comprising : determining that one of the spots is at least partly in the region ; determining which ones of the pixels in that region are part of the spot that is at least partly in that region ; determining a center. pixel for the pixels that have been determined to be in that spot ; and moving the region to be centered on the center pixel and repeating said determining threshold intensity and said determining whether one of the spots.
62. A method for automatically locating spots in an image based on intensities of pixels in the image comprising : determining an integrated intensity for each of a plurality of regions in the image ; sorting the integrated intensities in the regions in descending order ; and claiming some of the regions to contain spots based on determining the highest integrated intensity among the regions while setting the integrated intensities for the regions that overlap the claimed regions to be a lowest integrated intensity.
63. The method of claim 61 wherein said claiming comprises setting overlapping regions to zero.
64. The method of claim 61 wherein said determining comprises masking the regions when determining the integrating intensity in each one of the regions.
65. The method of claim 61 further comprising providing the regions to be approximately the size of a spot pitch for the spots in the image.
66. A machinereadable storage medium encoded with a set of machine executable instructions for using image analysis equipment to perform a method for automatically locating spots in an image based on intensities of points in the image, comprising : determining whether a current point in the image and two adjacent points, have intensities that are approximately above a minimum threshold intensity ; and identifying whether part of a new spot is located at the current point based only on the intensities of the two adjacent points when the current point has an intensity that is approximately above the minimum threshold intensity.
67. The machinereadable storage medium of claim 65 wherein said determining in said method comprises determining whether the current point and the two adjacent points have intensities that are approximately within a threshold range comprising the minimum threshold intensity and a maximum threshold intensity.
68. The machinereadable storage medium of claim 65 wherein said identifying in said method comprises identifying based only on the two adjacent points when the current point is approximately within the threshold range.
69. The machinereadable storage medium of claim 65 wherein said method further comprising providing a plurality of pixels that are representative of the points in the image.
70. The machinereadable storage medium of claim 68 wherein said determining and said identifying in said method comprises using a current pixel that corresponds to the current point and two of the pixels that are adjacent to the current pixel which correspond to the two adjacent points in said determining and said identifying.
71. The machinereadable storage medium of claim 69 wherein, said determining in said method comprises determining whether the current pixel and the two adjacent pixels have intensities that are approximately within a threshold range comprising the minimum threshold intensity and a maximum threshold intensity ; and said identifying in said method comprises identifying when the current pixel has intensity that is approximately within the threshold range.
72. The machinereadable storage medium of claim 69 wherein said method further comprising repeating said determining to evaluate the plurality of pixels by walking through the image pixelbypixel in lines of pixels.
73. A machinereadable storage medium encoded with a set of machine executable instructions for using image analysis equipment to perform a method of automatically locating spots in an image based on intensities of pixels in the image, comprising : determining whether a current pixel in the image and two pixels adjacent to the current pixel have intensities that are approximately within a threshold range ; identifying whether part of a new spot that is located at the current pixel based only on the intensities of the two adjacent pixels when the current pixel has an intensity that is approximately within the threshold range ; and repeating said determining and said identifying to identify a high density array of spots.
74. The machinereadable storage medium of claim 72 wherein said identifying in said method comprises identifying the current pixel to be part of a known spot when the two adjacent pixels have been identified to be part of that known spot.
75. The machinereadable storage medium of claim 72 wherein said identifying in said method comprises identifying the current pixel to be part of a known spot when one of the two adjacent pixels has been identified to be part of the known spot and the intensity of the other one of the two adjacent pixels has been determined to be approximately outside the threshold range.
76. The machinereadable storage medium of claim 74 wherein said method further comprising determining which ones of the other pixels are part of the new spot.
77. The machinereadable storage medium of claim 75 wherein said method comprising : determining whether any of the pixels that are determined to be part of the new spot are located at the edge of the image ; and rejecting the new spot in response to determining that the pixels in the new spot are located approximately at the edge of the image.
78. The machinereadable storage medium of claim 75 wherein said method further comprising determining that a particular pixel in the image is part of the new spot based on that particular pixel being substantially enclosed by some of the pixels that have been determined to be part of the new spot.
79. The machinereadable storage medium of claim 72 wherein said method further comprising identifying where another spot is located in the image based on determining an integrated intensity for a region that is centered on another one of the pixels.
80. A machinereadable storage medium encoded with a set of machine executable instructions for using image analysis equipment to perform a method for automatically locating spots in an image based on intensities of pixels in the image, comprising : searching for a first pixel that has an intensity that is approximately above a threshold intensity ; determining that a part of a new spot is located at the first pixel in response to said searching ; searching only nearest neighbors recursively starting from the first pixel to identify which ones of the pixels in the image are part of the new spot based on the threshold intensity ; and repeating said searching for a first pixel, said determining, and said searching to identify a high density array of spots in the image.
81. The machinereadable storage medium of claim 79 wherein said searching only nearest neighbors recursively comprises searching recursively starting from every pixel that is identified to be part of the new spot to identify which ones of the pixels in the image are part of that new spot.
82. The machinereadable storage medium of claim 79 wherein said searching for the first pixel comprises searching serially pixelbypixel in lines of pixels.
83. The machinereadable storage medium of claim 79 wherein said searching recursively comprises searching recursively until substantially all of the pixels that are contiguous with the first pixel and that have intensities that are approximately above the threshold intensity are identified.
84. The machinereadable storage medium of claim 82 wherein said method further comprising repeating said searching for a first pixel to locate another spot in response to identifying substantially all of the pixels that are part of the new spot.
85. A machinereadable storage medium encoded with a set of machine executable instructions for using image analysis equipment to perform a method for automatically locating spots in an image based on intensities of pixels in the image, comprising : searching serially for a first pixel that has an intensity that is approximately above a threshold intensity ; determining that part of a new spot is located at the first pixel in response to said searching ; and searching only nearest neighbors recursively starting from the first pixel to identify which ones of the pixels in the image are part of the new spot based on the threshold intensity.
86. The machinereadable storage medium of claim 84 wherein said searching serially and said searching only nearest neighbors includes searching each pixel in the image at most once.
87. The machinereadable storage medium of claim 84 wherein said method further comprising determining whether one of the pixels that are identified to be part of the new spot are located approximately at an edge of the image.
88. The machinereadable storage medium of claim 84 wherein said method further comprising determining that a particular pixel is part of the new spot based on that particular pixel being substantially enclosed by some of the pixels that are identified to be part of the new spot.
89. The machinereadable storage medium of claim 84 wherein said method further comprising determining where another spot is located based on determining an integrated intensity for a region in the image that is centered on another one of the pixels.
90. A machinereadable storage medium encoded with a set of machine executable instructions for using image analysis equipment to perform a method for automatically locating spots in an image. based on intensities of pixels in the image, comprising : determining an integrated intensity for each of a plurality of particularlyshaped regions that are each centered on one of a plurality of pixels in the image ; and identifying that a new spot is located in one of the regions based on the integrated intensity of that region in relation to the integrated intensities of the other regions.
91. The machinereadable storage medium of claim 89 wherein said determining comprises providing each of the regions to be approximately the size of a spot pitch for a plurality of spots that are in the image.
92. The machinereadable storage medium of claim 89 wherein said determining comprises masking each region before determining the integrated intensity.
93. The machinereadable storage medium of claim 91 wherein said masking comprises masking to sharpen spot characteristics.
94. The machinereadable storage medium of claim 89 wherein said determining comprises determining which one of the regions has a highest integrated intensity in relation to the rest of the regions to identify which one of the regions includes a new spot.
95. A machinereadable storage medium encoded with a set of machine executable instructions for using image analysis equipment to perform a method for automatically locating spots in an image based on intensities of pixels in the image, comprising : determining an integrated intensity for a plurality of particularlyshaped regions that are each centered on one of a plurality of pixels in the image ; determining which one of the regions has a highest integrated intensity in relation to the rest of the regions to identify which one of the regions includes a new spot ; and setting any of the regions that overlap the region having the highest integrated intensity to have a lowest integrated intensity.
96. The machinereadable storage medium of claim 94 wherein said method further comprising determining that a second spot is located in a next region having the next highest integrated intensity in relation to the other regions.
97. The machinereadable storage medium of claim 94 wherein said method further comprising determining a center point for the new spot based on a threshold intensity that is determined from the intensities of the pixels in the region in which the new spot was identified to be located.
98. The machinereadable storage medium of claim 94 wherein said determining which one comprises identifying that one of the regions includes the new spot based on characteristics of pixels that are in that region that are determined based on a threshold intensity.
99. The machinereadable storage medium of claim 94 wherein said method further comprising determining a location for another spot based on a threshold intensity.
100. A machinereadable storage medium encoded with a set of machine executable instructions for using image analysis equipment to perform a method for relating a plurality of spots that have been placed on a slide to a grid comprising grid points that were used in placing the spots on the slide, comprising : providing an image that is representative of the slide ; determining where the spots are located in the image ; mapping the grid on to the image using a plurality of test locations on the image as origins for the grid to determine a best origin for the grid in relation to the spots ; and assigning each spot to one of the grid points in the grid based on evaluating which grid point is nearest to the location of that spot.
101. The machinereadable storage medium of claim 99 wherein said providing comprises generating the image using a plurality of pixels that are each representative of approximately one of a plurality of points on the slide based on an intensity of the point that each pixel represents.
102. The machinereadable storage medium of claim 100 wherein said mapping comprises selecting one of the test locations to be the best origin based on a total intensity for pixels that are approximately within a selected distance from each grid point.
103. The machinereadable storage medium of claim 100 wherein said method further comprising selecting one of the test locations to be the best origin based on a total distance between every one of the grid points and the spot nearest to that grid point.
104. The machinereadable storage medium of claim 99 wherein said method further comprising determining a positional relationship of the grid points to each other based a spot pitch, pin pitch, number of rows and columns of spots, and number of rows and columns of printer pins of a spot printer that was used to place the spots on the slide.
105. The machinereadable storage medium of claim 99 wherein said method further comprising determining an actual spot pitch based on where spots are located in the image.
106. The machinereadable storage medium of claim 104 wherein said mapping further comprises adjusting the shape of the grid based on the actual spot pitch.
107. The machinereadable storage medium of claim 104 wherein said determining an actual spot pitch comprises determining a directional spot pitch vector by averaging vectors for pairs of nearest neighboring spots in approximately one direction.
108. The machinereadable storage medium of claim 104 wherein said determining an actual spot pitch comprises : sorting the spots based on where they are located in the image ; selecting a plurality of pairs of spots based on the sorted list ; and determining a spot pitch vector by averaging vectors for the selected pairs of spots.
109. A machinereadable storage medium encoded with a set of machine executable instructions for using image analysis equipment to perform a method for using intensities of pixels in a current image having a plurality of spots to filter further images comprising : identifying in a current image a plurality of similarlyshaped regions that each include one of the spots that each include a plurality of pixels ; and determining an average intensity profile for the regions based on averaging intensities for the pixels that are approximately in the same location in each of the identified regions ; and filtering intensities in further images using the average intensity profile.
110. The machinereadable storage medium of claim 108 wherein said identifying comprises centering each of the regions over the spot that is in that region.
111. The machinereadable storage medium of claim 108 wherein said filtering comprises filtering using the average intensity profile to weigh pixels in further images that are to be analyzed.
112. The machinereadable storage medium of claim 108 further comprising identifying spot'locations in the further images based on the filtered intensities.
113. A machinereadable storage medium encoded with a set of machine executable instructions for using image analysis equipment to perform a method for analyzing a plurality of spots that are placed on a slide to test expressions of a plurality of source materials in the spots based on a plurality of images that are each differently representative of the slide, wherein locations of the spots in the images have been determined, comprising : determining an aligned image for each of a plurality of the images based on the locations of spots in one of the plurality of images in relation to the location of spots in each of the other images ; determining a composite image based on the aligned images ; determining which areas in the composite image comprises spots ; and analyzing areas in one of the aligned images for expressions of one of the source materials based on the areas that were determined to comprise spots in the composite image.
114. The machinereadable storage medium of claim 112 wherein said method further comprising : providing for each of the plurality of the images a plurality of pixels that are each representative of a point on the slide being represented by that image ; and wherein said determining an aligned image, comprises aligning the pixels to form the aligned image for each slide.
115. The machinereadable storage medium of claim 113 wherein said aligning comprises applying a matrix transform on a pixelbypixel basis to determine the aligned, image for each slide.
116. The machinereadable storage medium of claim 113 wherein said determining an aligned image comprises : selecting one of the images to be a reference image ; and aligning the other images to the selected reference image.
117. The machinereadable storage medium of claim 113 wherein said providing comprises : providing each of the plurality of pixels to have an intensity of the point which that pixel represents ; and said determining a composite image, comprises combining light intensities for pixels that are approximately in a same location in each of the aligned images.
118. The machinereadable storage medium of claim 113 wherein said determining which areas, comprises determining which areas based on a threshold intensity for the pixels in the composite image.
119. The machinereadable storage medium of claim 113 wherein said determining which areas, comprises determining which areas based on an integrated intensity for each of a plurality of regions in the composite image.
120. A machinereadable storage medium encoded with a set of machine executable instructions for using image analysis equipment to perform a method for automatically determining where spots in an image are located based on intensities of a plurality of pixels in the image, comprising : determining a threshold intensity for a particular image region based on intensities of a portion of the pixels in that region ; and determining whether one of the spots is at least partly located in the region based on the threshold intensity determined for that region.
121. The machinereadable storage medium of claim 119 wherein said determining a threshold intensity, comprises using the portion to be approximately a size of an average spot.
122. The machinereadable storage medium of claim 119 wherein said method further comprising repeating for another region said determining a threshold intensity and said determining whether one of the spots to determine whether there are any spots in the other region.
123. The machinereadable storage medium of claim 121 wherein said repeating comprises selecting the other region based on a spot pitch for the spots in the slide and a current region.
124. The machinereadable storage medium of claim 119 wherein said determining whether one of the spots, comprises determining whether one of the spots is at least partly in the region based on characteristics of a group of the pixels in the particular region.
125. The machinereadable storage medium of claim 119 wherein said method further comprising : determining that one of the spots is at least partly in the region ; determining which ones of the pixels in that region are part of the spot that is at least partly in that region ; determining a center pixel for the pixels that have been determined to be in that spot ; and moving the region to be centered on the center pixel and repeating said determining threshold intensity and said determining whether one of the spots.
126. A machinereadable storage medium encoded with a set of machine executable instructions for using image analysis equipment to perform a method for automatically locating spots in an image based on intensities of pixels in the image comprising : determining an integrated intensity for each of a plurality of regions in the image ; sorting the integrated intensities in the regions in descending order ; and claiming some of the regions to contain spots based on determining the highest integrated intensity among the regions while setting the integrated intensities for the regions that overlap the claimed regions to be a lowest integrated intensity.
127. The machinereadable storage medium of claim 125 wherein said claiming comprises setting overlapping regions to zero.
128. The machinereadable storage medium of claim 125 wherein said determining comprises masking the regions when determining the integrating intensity in each one of the regions.
129. The machinereadable storage medium of claim 125 wherein said method further comprising providing the regions to be approximately the size of a spot pitch for the spots in the image.
130. A method of automatically locating objects in an image based on intensities of pixels in the image, comprising : determining whether a current pixel in the image and two pixels adjacent to the current pixel have intensities that are approximately within a threshold range ; and identifying whether part of a new object is located at the current pixel based only on the intensities, of the two adjacent pixels when the current pixel has an intensity that is approximately within the threshold range.
131. A method for automatically locating objects in an image based on intensities of pixels in the image, comprising : searching for a first pixel that has an intensity that is approximately above a threshold intensity ; determining that a part of a new object is located at the first pixel in response to said searching ; and searching only nearest neighbors recursively starting from the first pixel to identify which ones of the pixels in the image are part of the new object based on the threshold intensity.
132. A method for automatically locating objects in an image based on intensities of pixels in the image, comprising : determining an integrated intensity for each of a plurality of particularlyshaped regions that are each centered on a different one of a plurality of pixels in the image ; and identifying that a new object is located in one of the regions based on the integrated intensity of that region in relation to the integrated intensities of the other regions.
133. A method for automatically locating spots in an image based on intensities of pixels in the image, comprising : determining an integrated intensity for each of a plurality of particularlyshaped regions that are each centered on a different one of a plurality of pixels in the image ; identifying that a new spot is located in one of the regions based on the integrated intensity of that region in relation to the integrated intensities of the other regions ; and repeating said determining and said identifying to identify a high density array of spots in that image.
Description:
METHODS AND APPARATUS FOR IMAGE ANALYSIS Cross-Reference to Related Application This application claims the benefit of U. S. provisional patent application Serial No. 60/188, 398, filed March 10, 2000, which is hereby incorporated herein in its entirety.

Reference to Computer Program Listing Appendix This application includes a computer program listing appendix that includes code listings for programs with the following file names, align background. c, align images. c, background. c, create boxes. c, defs. h, draw-boxes. c, filters. c, find angles. c, find array. c, find boxes. c, find spots. c, free image. c, info. c, integrate regions. c, map_spots. c, mask. c, output_data. c, output image. c, overlap. c, ppm. c, quality. c, read_parameters. c, readprinterinfo. c, removeoverlappingboxes. c, setparameters. c, sort. c, spot type. c, statistics. c, string stuff. c, structure. h,

sum-images. c, tiff. c, write_jpeg. c, write tiff. c, wspots. c, and makefile. A c-compiler, such as the gnu- gcc computer tools, may be used to build a program with these files.

Background of the Invention This invention generally relates to image analysis, and more particularly to image analysis that is automated.

Image analysis is an important tool in solving many of today's technological problems. These problems may be faced in a wide range of sciences. For example, image analysis may be involved in technologies ranging from biological sciences to electronics.

In electronics for example, there are fields, such as, circuit tracing, machine vision control, machine motion control, or radar imaging, in which image analysis may be used. In biological science for example, there are fields, such as, cellular inspection, microassays, or band identification for electrophoresis in which image analysis may be involved. Known techniques of image analysis, however, have been deficient in appropriately meeting the demands on image analysis.

For example, in biomedical or biological research and testing, known techniques have been deficient in appropriately meeting the demands involved in analyzing densely grouped spots of genetic

materials, proteins, cells, etc. In such research and testing, drops of genetic materials, proteins, or cells may be placed densely on a supporting surface (e. g., a slide) to form a dense group of spots, such as a high density array. Each spot may contain a known element (e. g., molecules of DNA with a known sequence). Each spot may further include a label or tag (e. g., fluorophor, radioactive, etc.) that is used in obtaining visual expression of the known element through hybridization. On each supporting surface there may be hundreds of thousands of individual spots that are to be identified for analysis.

In some known techniques, spots in high density arrays are manually identified and analyzed by operators. Such techniques may be tedious due to the high number of spots that are involved and may include unsystematic and unpredictable errors (e. g., one operator may identify spots as being at slightly different locations on different days).

Known automated techniques have also been deficient for example, in satisfactorily meeting demands on speed, processing, accuracy, repeatability, object (e. g., spot) finding, mapping, etc.

In one known automated technique, pixels in a small simple image are searched serially to find a pixel that may have one of only two intensities. To find an island in the image, pixels may be searched recursively by searching all of the nearest neighbors

and next-to-nearest neighbors of pixels that have the higher one of the two intensities when a pixel having a higher one of the two intensities is reached during serial searching. Serial searching may resume when further pixels with the higher intensity are not found.

This known technique may also track which pixels have already been searched to prevent searching each pixel more than once. This technique may be deficient because it can not be applied to images having a wider range of pixel intensities, it cannot be applied to complex images quickly and accurately to locate islands, it may not meet speed and processing demands for complex images having a range of intensities, it can be inaccurate for images having a wide range of intensities, it may place a heavy burden on image analysis equipment, etc.

Summary of the Invention In accordance with the principles of the present invention, image analysis techniques may be provided.

For object analysis, locations of objects in an image may be determined by evaluating intensity at a plurality of pixels in the image. Such techniques may sometimes be referred to as thresholding techniques.

An object may be located by determining whether a current point in the slide may have an intensity that is approximately above a threshold intensity or, if

desired, approximately within an intensity threshold range.

A current pixel may be determined to be part of a new object based on characteristics of two pixels that adjacent to the current pixel. A current pixel may be determined to be part of a new object when an adjacent pixel above and an adjacent pixel behind the current pixel have intensities that are not at a desired light intensity (e. g., approximately below a threshold intensity, approximately within a threshold range, etc.). An adjacent pixel behind may be a pixel that may have been examined immediately preceding the current pixel. The current pixel may be determined to be part of a known object when either an adjacent pixel above or an adjacent pixel behind have been determined to be part of an object (a known object). When an adjacent pixel above and an adjacent pixel behind have been determined to be part of two different objects, a current pixel may be determined to be part of the same object as the adjacent pixel above and the adjacent object behind may be reassigned to be part of the same object as the adjacent object above. Other pixels that may have been assigned to the same object as the adjacent pixel behind may also be reassigned. If desired, whether a current pixel, which has a desired intensity, is part of a new object or a known object may be determined based only on two of eight pixels

adjacent to the current pixel (e. g., the adjacent pixel behind and the adjacent pixel above).

Pixels in an image may be evaluated in rows on a pixel-by-pixel basis. The determination of object locations may commence from a particular pixel in an image (e. g., upper-left corner, lower-left corner, etc.). Determinations of whether pixels are part of objects may be performed in parallel, in series, or in a combination thereof. If desired, for each pixel only one fourth of the pixels adjacent to that pixel may be used to determine the status of that pixel.

Pixels in an image may be searched to find a current pixel that has a desired intensity level.

Searching may be performed in rows on a pixel-by-pixel basis. A current pixel may be determined to be part of a new object when the current pixel has a desired intensity level. Nearest neighboring pixels of a current pixel that has a desired intensity may be recursively searched to find other pixels that have a desired intensity. The current pixel and the nearest neighboring pixels of the current pixel that have a desired intensity may be assigned to the same object.

Recursive searching may be repeated to determine a contiguous group of pixels that comprise an object.

Recursive searching may involve searching in select radial directions from a current pixel having a desired intensity (e. g., searching above, below, to the left, and to the right of a current pixel).

Locations of objects may be determined by integration of intensities of pixels in a plurality of regions. Such techniques may be sometimes referred to as integration techniques. A plurality of regions of approximately a same shape may each be centered on one of a plurality of pixels in an image. The sum of intensities within each region may be determined.

Intensity for each region may be associated with the pixel on which that region is centered. Intensity sums may be compared in relation to each other and a region having a highest intensity may be determined to include an object. Intensity sums for other regions that overlap a region that has been determined to include an object may be set to the lowest light intensity (e. g., zero). A region may be determined to include an object based on having the next highest intensity sum and intensity sums for regions that overlap that region may be set to the lowest intensity. Determining which region has a next highest intensity and setting intensity sums for regions that overlap that region may be repeated to find other objects on the slide. If desired, regions of approximately a same shape may be centered on substantially every pixel on a slide to determine locations of objects on the slide based on the sum of intensities in the regions.

If desired, integration techniques may be combined with thresholding techniques. For example, thresholding may be applied after integration to locate

objects in an integration region, to determine characteristics of spots in an integration region, etc.

If desired, integration regions may be repositioned based on determining a center of an object in a region using thresholding techniques. If desired, thresholding techniques may be applied to determine whether to discard or ignore regions based on characteristics of objects in the regions.

Objects may be masked using an average intensity profile. A plurality of regions may have been determined to include objects. The regions may be of approximately the same shape. Pixels that are approximately in the same location in each region may be combined to determine an average intensity profile for the object shape in those regions. The average intensity profile may be normalized and applied to objects that may have approximately a same shape as the objects in the regions used in determining the average intensity profile.

Thresholding, integration, and masking techniques may be applied to automatically locate objects in an image and to locate objects in an image having pixels of a wide range of intensities (e. g., at least three levels of intensities). In particular, these techniques and their combinations may be suitable for automatically locating objects that are spots or have a periodic structure, a densely grouped structure (e. g., high density arrays), etc.

In biomedical or biological image analysis applications, the objects that are being located may be spots, such as spots in a high density array. Spots may be mapped to grid points in a grid that may have been used to place the spots on a slide for analysis.

An image representative of a slide may be determined and locations of spots on the image may be determined.

Positional relationship of grid points to each other in a grid may be determined. A grid may be placed on an image and moved to locate a best location at which the grid points best match the spots. The grid may be moved to maximize total intensity of spots within a distance of the grid points. Each grid point may be mapped to a nearest spot. If desired, a grid that has grid points that have been mapped to spots may be moved to minimize distances between the grid points and the spots to which grid points have been mapped. Factors, such as image skew or slide rotation, may be compensated for by determining an actual spot pitch for the spots under analysis (e. g., a horizontal spot pitch or vertical spot pitch).

A plurality of unit cell spot pitch vectors may be determined by drawing a plurality of vectors that are approximately parallel and that point approximately in the same direction from a spot to a nearest neighboring spot. Unit cell spot pitch vectors may be averaged to determine an actual spot pitch and the actual spot pitch may be used in determining a grid

structure (e. g., relationship of grid points to each other). In determining the average, unit cell spot pitch vectors that do not meet certain tolerances may be excluded. If desired, pairs of spots for vectors may be determined by sorting spots based on row (or column) of the spots and selecting pairs based on where spots are located in the sorted list. If desired, an actual spot pitch for a subgrid may be determined by determining an actual spot pitch for spots that have been mapped to grid points in that subgrid.

Spots on a slide may contain material from two sources with each being tagged differently. Images that represent the slide may be generated with each image having different characteristics based on the characteristics of the tags. Spot analysis may involve locating spots in each image. Selecting one image as a reference image and aligning other image (s) to the reference image (e. g., using matrix transformation). A composite image may be generated based on the reference and aligned image (s). Locations of spots in the composite image may be determined and the locations may be used in analyzing spots on the reference image and aligned image (s).

Objects (e. g., spots) that have been located or mapped may be analyzed to obtain information about the characteristics of the objects.

Equipment for spot analysis that implements such techniques may include hardware resources

(processing device, storage device, output device, scanning device, input/output device, etc.) and may include application resources (operating system, device drivers, spot array application, etc.). Spot analysis techniques may be provided for execution on a machine- readable storage medium that may include a set of instructions for performing such techniques.

Brief Description of the Drawings Further features of the invention, its nature and various advantages will be more apparent from the following detailed description, taken in conjunction with the accompanying drawings in which like reference characters refer to like part throughout, and in which : FIG. 1 is a diagram of illustrative equipment for image analysis in accordance with the present invention ; FIG. 2 is a diagram of an illustrative slide having illustrative objects thereon for image analysis in accordance with the present invention ; FIGS. 3a-3e are diagrams of an illustrative group of pixels for which thresholding techniques have been applied in accordance with the present invention ; FIG. 3f is a flow chart of illustrative steps involved in automatically locating objects in an image in accordance with the present invention ;

FIGS. 4a-4f are diagrams of illustrative groups of pixels for which thresholding techniques have been applied in accordance with the present invention ; FIGS. 5a-5f are diagrams of an illustrative group of pixels for which thresholding techniques have been applied in accordance with the present invention ; FIG. 5g is a flow chart of illustrative steps involved in automatically locating spots in an image using furcation in accordance with the present invention ; FIG. 6a is a diagram of an illustrative image for which edge-rejection techniques have been applied in accordance with the present invention ; FIG. 6b is a diagram of an illustrative group of pixels for which hole-filling techniques have been applied in accordance with the present invention ; FIGS. 7a-7c are diagrams of an illustrative subsection of an image for which integration techniques have been applied in accordance with the present invention ; FIG. 8a is a flow chart of illustrative steps involved in integration techniques in accordance with the present invention ; FIG. 8b is a flow chart of illustrative steps involved in claiming which one of a plurality of regions contains an object in accordance with the present invention ;

FIG. 9 is a diagram of an illustrative subsection of an image for which integration and thresholding techniques have been applied in accordance with the present invention ; FIG. 10 is a flow chart of illustrative steps involved in identifying a best object in a region in accordance with the present invention ; FIGS. lla-lld are diagrams of an illustrative subsection of an image for which thresholding techniques have been applied to determine whether to discard a region in the image in accordance with the present invention ; FIGS. 12a-12c are diagrams of an illustrative subsection of an image for which thresholding techniques have been applied to determine whether to discard a region in the image in accordance with the present invention ; FIGS. 13a-13c are diagrams of an illustrative subsection of an image for which thresholding techniques have been applied to center a region on an object in accordance with the present invention ; FIG. 14 is a flow chart of illustrative steps involved in moving a region to center on an object in accordance with the present invention ; FIG. 15 is a diagram of an illustrative subsection of an image for which thresholding and integration techniques have been applied in accordance with the present invention ;

FIG. 16 is a flow chart of illustrative steps involved in masking spots in accordance with the present invention ; | FIG. 17a is a diagram of an illustrative sequence involved in determining an average intensity profile in accordance with the present invention ; FIG. 17b is a diagram of an illustrative mask that may be applied to weigh pixels in accordance with the present invention.

FIG. 18 is a flow chart of illustrative steps involved in mapping spots to grid points in accordance with the present invention ; FIG. 19 is a diagram of an illustrative image for which mapping has been applied in accordance with the present invention ; FIG. 20 is a diagram of an illustrative mapping sequence involved in mapping spots to grid points in accordance with the present invention ; FIG. 21 is a flow chart of illustrative steps involved in determining a grid structure in accordance with the present invention ; FIG. 22 is a flow chart of illustrative steps involved in determining spot-pitch vectors in accordance with the present invention ; FIGS. 23a and 23b are diagrams of illustrative spots for which spot-pitch vectors are being determined in accordance with the present invention ;

FIG. 24 is a flow chart of illustrative steps involved in determining pairs of spots for determining spot-pitch vectors in accordance with the present invention.

FIG. 25 is a flow chart of illustrative steps involved in mapping based on subgrid-pitch vectors in accordance with the present invention ; FIGS. 26a and 26b is a flow chart of illustrative steps involved in determining information on two source materials in accordance to the present invention ; FIGS. 27a-27f are diagrams of an illustrative slide and illustrative images for which techniques for determining data about two different source materials have been applied in accordance with the present invention ; FIG. 28 is a flow chart of illustrative steps involved in image analysis in accordance with the present invention ; FIG. 29 is a cross-sectional view of a magnetic data storage medium encoded with a set of machine-executable instructions for performing the method according to the present invention ; and FIG. 30 is a cross-sectional view of an optically readable data storage medium encoded with a set of machine executable instructions for performing the method according to the present invention.

Skilled artisans will appreciate that in may cases, elements in the FIGS. are illustrated for simplicity and clarity and have not necessarily been drawn to scale. For example, the dimensions of some of

the elements in certain FIGS. may be exaggerated relative to other elements to help improve understanding of what is being done.

Detailed Description of Preferred Embodiments With reference now FIG. 1, equipment 20 may be used for image analysis and may include hardware resources 22 and software resources 24. Hardware resources 22 may include a processing device (e. g., a processor, CPU, etc.), storage device (e. g., RAM, ROM, disk drive, etc.), output device (e. g., printer, monitor, etc.), input/output device (e. g., floppy disk drive, network connection, etc.), scanning device (e. g., scanner, light sensing device, etc.), etc.

Application resources 24 may include an operating system, device drivers, an image analysis application (e. g., image analysis application for analyzing high density arrays), etc. Together, hardware resources 22 and software resources may comprise a computer (e. g., a Sun workstation, Silicon Graphics workstation, etc.) including a scanner and a specific application for image analysis. Hardware resources 22 may have sufficient processing and storage capability to appropriately implement software resources, such as the image analysis application.

The scanning device may be a device that is configured to scan an area of interest (e. g., a biomedical or biological slide, a printed circuit

board, etc.) to determine intensity characteristics of points in the area. Intensity characteristics of points in the slide may be transmissive of reflective light intensity of points in the area or may be intensity that is not based on determining light intensity such as when fluorophors or =-particles (radio labels) are used. The scanning device may generate data that is representative of points (e. g., intensity of points, location of points, etc.) The data may be used to generate pixels that are each representative of a point in the area of interest.

Pixels may be of approximately a same shape as corresponding points that are represented by the pixels. The pixels may form an image that is representative of the area of interest.

Data from the scanning device may be used by equipment 20 in image analysis. Such data (e. g., an image of the area of interest) may be provided to equipment 20 via the input/output device of hardware resources 22. Data for image analysis may be provided to equipment 22 through sources other than the scanning devices (e. g., a network connection, storage device, etc).

With reference now to FIG. 2, an illustrative area of interest may be slide 10 having a high density array of illustrative objects that are spots for image analysis. Slide 10 may. include a periodic structure of spots. However, an area of interest may include any

type of object in any pattern. Each spot 12 may include material such as genetic material, proteins, cells, etc. that have been placed in slide 10. Spots 12 may have been placed on the slide in a known pattern. The spots 12 may have been placed on the slide in approximately regularly spaced intervals (e. g., 100 micron intervals) to form a high density array. Each spot 12 may have different intensity characteristics based on the material that it contains.

Slide 10 may be scanned with a scanning device to generate data that is representative of intensities of points on slide 10. Data may have been generated in increments that are each sufficient for generating a pixel that is representative of a corresponding point on the slide. If desired, data for pixels may be generated in series, in parallel, or in a combination thereof. For clarity and brevity, the techniques discussed herein are primarily discussed in the context of pixels that are representative of points in a scanned area of interest, rather than in the context of data used to generate the pixels or in the context of the points that are represented by the pixels. Moreover, the techniques discussed herein are discussed primarily in the context of spots to aid in the clarity and brevity of the discussion and for illustrative purposes.

An image may be a grey-scale image that includes various pixel intensities.

Analyzing characteristics of objects, such as spots, may involve automatically determining the locations of spots in an image. Locations of spots may be determined based on thresholding techniques. With reference now to FIG. 3A, pixels 30 may be a portion of an image that is representative of an area of interest, such as a slide having a high density array of spots thereon. Pixels 30 may be examined by spot locating equipment (e. g., equipment 20 of FIG. 1) to locate spots based on a selected threshold intensity. The equipment may start the analysis from a desired location in the image, such as from one corner of the image (e. g., top left corner). Pixels may be examined consecutively in rows walking across the image in one direction (e. g., left to right). Pixels that have intensities approximately above threshold intensity may be identified to be part of a new spot or may be identified to be part of a known spot. For example in FIG. 3A, each pixel in the first row of pixels 30 is examined in series to determine whether the intensity of a current pixel is approximately above a threshold intensity. Pixels 30 may be evaluated one at a time in a left to right direction sweeping across the image.

When a row has been evaluated, the analysis of the pixels may move to the next row.

In the next row, pixel 32 that has an intensity that is approximately above the threshold may be reached and may be identified to be part of a spot.

Pixel 32 may be determined to be part of a newly found spot based on adjacent pixels that have already been examined, such as the pixels above and behind pixel 32.

Pixel 33 that is behind pixel 32 may be the last pixel that was examined before pixel 32. Pixel 32 may be determined to be part of a new spot when adjacent- examined pixels 31 and 33, and the pixels above and behind pixel 32, have been determined to not be part of any spots.

Pixel 34, the next pixel in that row of pixels, may be evaluated next and determined to be a part of a new or known spot based on pixel 34 having an intensity that is approximately above the threshold intensity. The status of pixel 34 may be determined by pixel 35, the pixel that is above pixel 34 (that has an intensity that is approximately below the threshold), and pixel 32, the pixel that is behind pixel 34, that was already determined to be part of a spot.. Pixel 34 may then be identified to be part of the same spot as the pixel behind, pixel 32.

Pixel 36 (FIG. 3d) may be automatically identified to be part of the same spot as pixel 32 when the intensity of pixel 36 is determined to be approximately above the threshold intensity and an adjacent pixel above (pixel 32) or an adjacent pixel behind (pixel 37) has been identified to belong to a spot (e. g., the spot which pixel 32 was identified to be a part of). Such analysis may be repeated for pixel

38 (FIG. 3e). Pixel 38 may be examined and identified to have an intensity that is approximately above the threshold intensity. Pixel 38 may be determined to be part of the-same spot as pixels 32, 34 and 36 because one or more of the adjacent pixels that are above and behind pixel 38 were determined to be part of that particular spot. Analysis of the image that includes pixels 30 may involve walking through the image on a pixel-by-pixel, row-by-row basis (e. g., searching for pixels with appropriate characteristics) to determine whether a current pixel has an intensity that is approximately above a threshold intensity, determine whether a current pixel having an intensity approximately above a threshold intensity has an adjacent pixel behind or above that was already determined to be part of a known spot, identifying a current pixel having an appropriate intensity to be part of the same spot as the pixel behind or above the current pixel where at least one of the pixels above or behind has an intensity that is approximately above the threshold intensity, identifying a current pixel having an appropriate intensity, an intensity approximately above a threshold intensity, to be part of a new spot when neither the pixel behind nor above the current pixel has been determined to be part of a spot, etc.

Illustrative steps involved in automatically identifying objects in an image based on pixel intensities are shown in FIG. 3f. Pixels in an image

are examined sequentially (e. g., in series) starting from some yet unexamined pixel to find a current pixel that has a desired intensity at step 260. The desired intensity may be selected based on a threshold intensity (e. g., an intensity that is approximately above a selected threshold intensity for the pixels in the image). At step 262, a current pixel that has a desired intensity may be identified to be part of a new object that has not yet been identified in that image or part of a known object in that image based on particular pixels that adjoin the current pixel. The adjoining pixel may for example, be two pixels (e. g., only two pixels) that adjoin (e. g., immediately adjoin) the current pixel that have been already examined.

Step 262 may include substep 262a that includes identifying the current pixel to be part of a known object based on at least one of two adjoining pixels having been determined to be part of that known object.

For example, when a pixel above or a pixel behind the current pixel is part of an object, the current pixel may be identified to be part of that known object.

Identifying the current pixel to be part of the object also helps to identify the areas in the image in which that object is located and helps determining characteristics of that object. Step 262 may also include substep 262b that includes identifying the current pixel to be part of a new object when neither one of two adjoining pixels were determined to be part

of any objects. For example, a current pixel having a desired intensity that has a pixel above and a pixel behind that have been examined and determined not to be part of any objects may be identified to be part of a new object. This may also identify partly where that new object is located in that image. These steps may be repeated to identify other objects and to identify the pixels that are part of each of those objects.

These thresholding techniques may generally be suitable for automatically identifying objects and automatically locating objects in an image. In particular, these techniques may be suitable for automatically identifying or locating objects in an image having a periodic structure or high density structure, such as a high density array of spots.

In identifying whether a current pixel is part of a new or known object, a conflict may exist between the object characteristics of adjoining pixels.

For example, the pixel above may have been determined to be part of one spot and the pixel behind may have been determined to be part of another spot. With reference now to FIGS. 4a-4f, pixels 40 of FIG. 4a illustrates when a current pixel may be determined to be part of a new spot. Pixels 42 of FIG. 4b and pixels 44 of FIG. 4c illustrate when a current pixel may be determined to belong to a known spot. A conflict arises when, for example, Pixel 46 of FIG. 4b, which may be a current pixel, may be determined to equally be

part of one of two known spots. In pixels 46, pixel 48, which is the pixel above pixel 50, may have been determined to be part of a first spot. The pixel behind pixel 50, pixel 52, may have been determined to be part of a second spot. The current pixel, pixel 50, may then be part of the first or second spots. One way of identifying pixel 50 may be to assign pixel 50 to the first spot and to reassign the pixel behind, pixel 52, to the first spot. Other pixels that may have been assigned to the second spot (e. g., pixel 54) may also be reassigned to the first spot. With this technique, such a conflict is resolved by identifying the current pixel and the two conflicting adjoining pixels to the same spot. Additionally, other pixels that were previously determined to be part of the same spot as one of the two conflicting pixels may be reassigned to be part of the same spot as the current pixel.

In locating spots, an intensity threshold range may be used that may provide a range of light intensities that are indicative of whether a pixel is part of a spot. For clarity and brevity, techniques discussed herein are primarily discussed in the context of a threshold intensity..

If desired, in the thresholding techniques discussed herein, pixels may be evaluated in series, in parallel or in a combination thereof.

With reference now to FIGS. 4e and 4f, pixels 41 may represent a plurality of points in an image that includes a portion of one of the spots in that image. Pixels 41 may have been assigned a value indicating an intensity for the pixel.

If desired, pixels that have intensities that are approximately below the threshold intensity or approximately outside the intensity range may be determined to be pixels that are outside of any particular spot. Thresholding techniques that involve examining two adjacent pixels of a current pixel may identify contiguous regions of pixels that identify locations of individual spots.

Spots may be located using recursive types of thresholding techniques. Such techniques may sometimes be referred to as furcation. Pixels 50 may be searched to locate a current pixel that has an intensity that is approximately above a threshold intensity. Pixels 50 may be searched one at a time (e. g., pixel-by-pixel).

If desired, pixels may be searched in series, in rows, or in a combination thereof. As shown in FIG. 5a, pixels 50 that are in the first row may be examined in series. The examination may continue to other pixels in that row and to the next row. Searching may have commenced at the upper-left corner of the image. If desired, searching may have commenced at another point on the image. If desired, searching may be conducted in lines of pixels or in other patterns.

When searching pixels 50, pixel 52 may be reached and determined to be part of a new spot based on pixel 52 having a desired intensity (e. g., approximately above a threshold intensity, approximately within a threshold range, etc.).

Starting from pixel 52, recursive searching may be conducted. The nearest neighbors of pixel 52 may be recursively searched to find a contiguous region of pixels that are part of the new spot. Recursive searching of the pixels that are adjacent to pixel 52 (e. g., searching pixels that are adjacent to pixel 52 in a plurality of directions) may result in determining that adjacent pixel 54 has a desired intensity.

Adjacent pixels of pixel 54 may be searched, searched recursively, to find other pixels that belong to'that spot. If desired, searching may involve only searching pixels that have not yet been examined or searching each pixel only once. For example, as shown in FIGS. 5c and 5d, searching may involve only searching pixels that have not yet been examined. Pixels 56 and 58 may be determined to be part of that spot when pixels adjacent to pixel 54 are searched. Pixels adjacent to pixels 56 and 58 may be searched recursively to find other contiguous pixels that belong to that same spot and to identify where in that image that spot is entirely located.

Pixel 60 may be determined to be part of that spot when pixels adjacent to pixels 56 and 58 are

searched. Pixels adjacent to pixel 60 may be searched recursively to find other contiguous pixels that belong to that same spot and to further identify where in that image that spot is entirely located.

Searching for neighbors of pixel 52 in a recursive pattern may cease when substantially all pixels that are contiguous with pixel 52 and that have a desired intensity have been identified (e. g., the pixels in the current spot). When recursive searching is ceased, searching of other pixels may be started in a pattern that may have been used to reach pixel 52.

Recursive searching of pixels may resume when a pixel is encountered that has a desired intensity and that has not yet been assigned to be part of a spot. FIG.

5f includes spot 62 that may have been represented by pixels 52, 54, 56, 58 and 60. The rest of an image that includes pixels 50 may be searched with such techniques to locate other spots in the image. When using computers to implement such recursive techniques, an internal stack space may have to be manually created with a size that is dependent on the possible size of spots in the image.

In one embodiment of the present invention, only nearest neighbors are recursively searched. For example, as shown in FIG. 5a-5e, only the pixels that are immediately above, below, to the left, and to the right of a pixel having a desired intensity are searched. Recursive nearest neighbor searching may be

performed until no new pixels that have the desired intensity are found. Searching only nearest neighbors recursively should be performed without searching next- to-nearest neighbors that would involve searching diagonally. As mentioned above, pixels that are already searched may not be searched again.

Illustrative steps involved in automatically identifying objects in an image based on recursively examining pixel intensities are shown in FIG. 5g.

Pixels in an image may be examined sequentially starting from some yet unexamined pixel to find a current pixel that has a desired intensity (step 264).

At step 266, a current pixel that has a desired intensity may be identified to be part of a new object that has been located. In addition, other pixels may be recursively searched starting from the current pixel to find other pixels that are part of that newly found object. For example, by recursively searching only nearest neighbors starting from the current pixel, substantially all of the pixels that are part of the new object may be identified. Recursive searching may cease when pixels that do not have a desired intensity are reached (e. g., the boundary of the object is reached). These steps may be repeated to identify other objects and to identify the pixels that are a part of each of these objects. If desired, pixels that have been searched may be tracked or another technique may be used to prevent redundant searching of pixels.

For example, each pixel may be searched once at most.

These thresholding techniques may generally be suitable for automatically identifying objects and automatically locating objects in an image. In particular, these techniques may be specially suitable for automatically identifying and locating objects or images having a periodic structure or high density structure, such as a high density array of spots.

Variations in recursive searching may involve using the location of pixels to determine whether pixels are part of an object.. For example, spots or pixels that are at the edges of an image may be evaluated based on their location. With references now to FIG. 6a, identifying spots may be performed by walking through the pixels along the perimeter of image 70 to find spots and then exploring interior 72. Spots that are at the edge of image 70 may be rejected. Such techniques may sometimes be referred to as edge- rejection techniques. Edge-rejection techniques may be used in combination with other image analysis techniques, such as those discussed herein.

Another variation may involve pixels that are surrounded by pixels that are part of an identified spot. For example, as shown in FIG. 6b, pixel 74 may include a region of pixels 76 that may have been determined to be part of a spot based on the intensities of pixels 76. Pixels 74 may also include three pixels that are each without a desired intensity

and that are substantially within the region of pixels 76. The three pixels may be assigned to the same spot as pixels 76 based on the three pixels being substantially within pixels 76. In one such technique, the pixels along the perimeter of the region of pixels 76 may be searched to flag all pixels that are without the desired intensity. The remaining pixels, the pixels within the flagged perimeter are assigned to belong to a spot. Such techniques may sometimes be referred to as hole-filling techniques.

If desired, hole-filling techniques may be performed in combination with other spot analysis techniques, such as, those discussed herein (e. g., edge-rejection techniques).

Thresholding techniques may be used to obtain information about spots such as average radius, area, perimeter, coefficients of roundness, center of mass, average position, etc. In general, morphological properties of spots may be determined using thresholding techniques.

Techniques discussed herein may be used in ways other than with pixels or images. For example, characteristics of a plurality of points on a surface may be analyzed. A point scanning device (e. g., a device that determines intensity of points on a surface one point at a time) may be configured to automatically apply techniques discussed herein. Equipment may be used to determine locations of a plurality of points on

a surface and to determine intensity characteristics for each point when applying such techniques (e. g., using furcation, hole-filling, etc.). For clarity and brevity, apparatus and methods sometimes discussed herein are discussed primarily in the context of pixels and images.

Location of objects in an image may be determined by examining a plurality of regions. For example, intensities in a plurality of regions may be used to locate spots. Such techniques may sometimes be referred to as integration techniques. For example, with reference now to FIGS. 7a-7c, pixel 78 in image 82 (a portion of image 82 is shown) may be selected and a sum of intensities for pixels in region 80 centered on pixel 78 may be determined. The region may be square in shape. If desired, other shapes may be used. The size of a region may be approximately equal to the spot pitch for spots that are in image 82. The intensity sum for region 80 may be associated with pixel 78. A next pixel, pixel 84, may be selected and a sum of intensities for pixels in region 86 centered on pixel 84 may be determined. Region 86 may be approximately the same size and shape as region 80. A third pixel, pixel 88, may be selected and a sum of intensities for pixels in region 90 centered on pixel 88 may be determined. Region 90 may be approximately the same shape and size as regions 80 and 86. Selection of pixels and summing of light intensities for regions of

approximately the same shape and size centered on one of the pixels may be repeated for the rest of image 82.

Distance intervals between selected pixels (e. g., pixels 78, 84, and 88) may be one pixel (e. g., pixels 78 and 84 may be adjacent, pixels 84 and 88 may be adjacent, etc.). A distance interval may sometimes be referred to as a step size. Pixels may be selected one pixel at a time in lines of pixels (e. g., rows, columns, etc.).

If desired, selection of each of a plurality of pixels may be performed in series, in parallel or in a combination of the two. Determination of sums of intensities that are each centered on one of the selected pixels may be performed in series, in parallel, or in a combination thereof.

Illustrative steps involved in locating objects, such as spots, based on intensity sums of regions are shown in FIG. 8a. At step 92, the sum of pixel intensities in each of a plurality of regions may be determined. The regions may be regions such as regions 80, 86, and 90 of FIGS. 7a-7c. At step 94, one of the regions may be identified to a spot based on the sum of pixel intensities in that region (e. g., the region with the highest intensity sum may be identified to include a spot). That region may be assigned to that spot. At step 96, regions that overlap the identified region may be rejected by setting the intensity sums for the overlapping regions to zero.

Steps 94 and 96 may be repeated to locate other regions in the image that include spots (e. g., a region with the next highest light intensity sum and setting light-intensity sums for regions overlapping the assigned region to zero). If desired, steps 94 and 96 may be repeated for an entire image to locate spots in the image. These integration techniques may generally be suitable for automatically identifying or locating objects in an image. In particular, these techniques may be specially suitable for automatically identifying and'locating objects in images having a periodic structure or high density structure, such as in high density arrays of spots.

Illustrative steps involved in claiming such regions in an image to include spots based on integrated intensities (intensity sums) of regions in the image are shown in FIG. 8b. At step 268, an integrated pixel intensity for a each of a plurality of regions in an image may be determined. The integrated intensities may be determined using regions such as the regions discussed above in FIGS. 7a-7c. At step 270, the integrated intensities for the regions may be sorted in descending order. At step 272, regions may be claimed based on determining which one has the highest integrated intensity. The region with the highest integrated intensity is claimed to include a spot and the regions that overlap the claimed spot are set to zero. The claiming of the region having the

highest integrated intensity while setting regions overlapping the claimed region to zero may be repeated to claim a plurality of regions to spots. The image may be analyzed further by performing the steps 268, 270, and 272, in repeated iterations, to find other spots that may have been missed in earlier iterations.

Regions that were claimed in a previous iteration may be excluded from the analysis in later iterations. In one variation of this technique, before a region is claimed, the region is analyzed to determine whether the region can be centered on a spot that is in the region. Regions that can be centered are claimed.

Illustrative techniques for centering are discussed below in connection with FIGS. 13a-13c and FIG. 14.

Such claiming techniques may be particularly suitable for locating objects on an image when the approximate shape, size, or structural relationship (e. g., spot pitch vector) for the object are known.

One advantage of integration techniques may be the techniques'ability to handle a wide dynamic range of intensities for spots.

Thresholding and integration techniques may be combined to locate objects. Thresholding techniques may be applied to locate objects within a portion of a region used in integration techniques. The portion may have a common center with the region. A threshold light intensity or threshold range may be varied from portion to portion.

Thresholding techniques may be used with integration techniques for screening purposes. For example, with reference now to FIG. 9, portion 98 of image 100 (a subpart of image 100 is shown) may have a center that is common with the center of region 102 that may have been used in performing integration techniques. Portion 98 may be approximately the size of region 102. The size that is selected for portion 98 may be too large when spots that belong to other regions may fall within portion 98 (e. g., when portion 98 has a size that is greater than the size of region 102). The size selected for portion 98 may have been selected to be too small when portion 98 has a length or width that is smaller than a predicted diameter for the spots. A threshold range for portion 98 may be selected, for example, by selecting an average light intensity for pixels in region 102 to be the lower bound of the threshold intensity and selecting a maximum possible light intensity to be an upper bound.

Spots 104 and 106 may be identified using thresholding techniques in portion 98. Properties of spots 104 and 106, such as intensity, average radius, location of spot in region, distances of spot to region center, etc., may be also determined using thresholding techniques and a best spot (e. g., spot 104) may be retained.

Illustrative steps involved in using thresholding techniques for screening purposes with

integration techniques are shown in FIG. 10. At step 108, thresholding techniques may be used in a portion of a region, such as a region that may have been used in an integration technique. Step 108 may include determining a threshold range for that portion (substep 108a). Using thresholding technique, more than one contiguous group of pixels, (more than one spot) may have been determined to be in the portion. At step 110, the best object in the portion may be determined.

At step 112, characteristics of the best object may be determined.

Thresholding techniques may be used with integration techniques to determine whether there are spots in an integration region that may have a size that is approximately greater than a selected minimum size. With reference now to FIGS. lla-llc, region 114 centered on pixel 116 may have been used in determining spots using integration techniques. Thresholding techniques may be applied to portion 118 of region 116.

Using thresholding techniques, spots 120, 122, and 124 may be determined to be located in portion 118. The characteristics of spots 120, 122, and 124 may be determined and whether to discard region 114 based on the determined characteristics of spots 120, 122, and 124 may be determined. Spots 120, 122, and 124 may each be determined to each have a size that is approximately below a minimum size and based on that determination, region 114 may be discarded. Region 114

may be discarded by setting intensity sum for region 114 to zero, by ignoring that region when determining which integration region has a highest light intensity (e. g., ignoring that region in step 94 of FIG. 8a), etc.

With reference now to FIG. lid, a best spot in region 115 may be determined based on a number of criteria. Thresholding techniques may have been performed in portion 123 of region 115 to identify spots such as spot 117, spot 119, and spot 121. A best spot may be selected based on the size of the spots, how for the spots are located from center pixel 116, the shape of the spots, the locations of the spots, combinations thereof, or any other suitable criteria.

For example, in FIG. lld, spot 117 may be determined to be the best spot in region 115 based on spot 117 having a size that is greater than each of spots 119 and 121.

If distance to center pixel 116 is the criteria, spot 119 may be selected to be the best spot because it the spot closest to center pixel FIG. lllb. Spot 121 may be selected to be the best spot when for example, the shape of the spots is used as the criteria for automatically selecting the best spots.

Thresholding techniques may be used with integration techniques to determine whether a spot in an integration region is approximately within a distance of the center of the integration region. With reference now to FIGS. 12a-12c, thresholding techniques

may be applied in portion 130 of integration region 126 that is centered on pixel 128. Spot 132 may be determined to be located in portion 132 and characteristics of spot 132 may be determined.

Characteristics may be characteristics such as, the distance within which spot 132 may be from pixel 128.

If desired, when multiple spots have been determined to be located in a portion, the characteristics of the largest one of the multiple spots may be used. If desired, integration region 126 may be discarded when spot 132 is not approximately within a minimum distance (e. g., three pixels) from the center pixel, pixel 128.

If desired, thresholding techniques may be used during integration techniques, after integration techniques, or in a combination thereof.

Thresholding techniques may be used with integration techniques to center an integration region to a spot that has been determined to be located in that region. If desired, thresholding techniques may be applied after a plurality of integration regions have been identified to include spots. With reference now to FIGS. 13a-13c, region 134 centered on pixel 138 may have been determined to include a spot using integration techniques. Thresholding techniques may have been applied to determine a location of spot 136 in region 134 and to determine a center pixel 140 for spot 136. Thresholding techniques may have been applied to a portion of region 134 that is

approximately the same shape and size as region 134 to determine the location of spot 136. Region 134 may be moved to be centered on center pixel 140 when center pixel 140 is not within some minimum distance of pixel 138. Thresholding techniques may be applied again to identify the pixels that are part of spot 136 and to determine a center for spot 136 in repositioned region 134 (e. g., center pixel 142). If desired, applying thresholding techniques to move region 134 may cease after this one iteration. When center pixel 142 is outside of a minimum distance from pixel 140, region 134 may be moved again to be centered on center pixel 142. Thresholding techniques may be applied to region 134 that is centered on pixel 142 to determine where spot 136 is located in region 134 and to determine whether center of spot 136 in region 134 is within a minimum distance of pixel 142. Thresholding techniques may be applied to other regions when region center pixel 142 is within a minimum distance to a spot center.

Illustrative steps involved in moving a region (e. g., as shown in FIGS. 13a-13c) are shown in FIG. 14. At step 144, a region of an image may be identified to include a type of object (e. g., that region has been assigned a spot). At step 146, a center for the object in the region may be determined (e. g., a thresholding technique may be applied to a portion of the region to determine a center of mass for

the object in that region). At step 148, a minimum distance relationship between the object center and the center of the region may be determined. Additional regions may be evaluated when the distance relationship is determined to be sufficient. Whether the center of the object and of the region are converging may be evaluated when the distance relationship is not sufficient. Convergence may be evaluated by determining how many times the region may have already been moved and whether a maximum number of movements has been reached. At step 152, the region may be moved to be centered on the determined spot center in response to determining that the spot center and region center may converge. If desired, steps 146, 148, 150, and 152 may be repeated until that region has been moved a maximum number of times (e. g., object center and region center are not converging) or until object and region centers have substantially converged.

Regions that may have been moved, but which may have not been determined to be converging may be discarded.

Integration techniques may be applied to an image again after aligning a plurality of objects and regions to identify other regions that may include spots that were missed when integration techniques were applied.

Other techniques that combine thresholding techniques and integration techniques may be used. For example, as shown in FIG. 15, image 154 (a subsection of image 154 is shown) may include a plurality of spots

156. Thresholding techniques may be applied to image portions (e. g., portion 158) that are large enough to approximately contain a nearest spot (e. g., spot 160).

The approximate size of spots in the image may have been known, for example, from the techniques that may have been used to-form the spots. The image may be analyzed by stepping (e. g., steps 162, 164, etc.) through a plurality of portions using step sizes that are approximately between one and one half of a spot pitch for spots that are in that image. The spot pitch may be known based on knowing how the spots were formed in an image.

A particular threshold intensity may be set for a portion based on an integrated intensity for the region (e. g., region 166) that is centered over that thresholding portion (e. g., portion 158). Portions that may have been determined to include spots may be evaluated to determine whether the portion and/or spot meet some criteria (e. g., spot size, distance to the center of portion, etc.). One criterion may be that the center of the spot found in the current portion is not approximately more than the V2 * (step size)/2 pixels from the center of the current portion. A portion may be determined to include a spot (e. g., assigned to a spot) when a group of pixels in that portion has been determined to meet some criteria. If desired, portions that may overlap the portion determined to include a spot may be ignored in

determining which other portions include spots.

Overlapping portions may be ignored after a particular portion has been determined to include a spot, after stepping through an image, or a combination thereof.

Integration, thresholding, centering, claiming, and iteration may be combined in a number of suitable ways. For example, an image may be analyzed by using integration and thresholding to claim that particular box-shaped portions of the image include spots with appropriate properties. Thresholding techniques may be used to center the claimed boxes (e. g., using techniques described in connection with FIGS. 13a-13c and FIG. 14). Boxes that fail to be centered are rejected and boxes that are centered are retained. Claiming and centering are iterated to find other boxes that can be centered. Iterations may cease when the number of boxes that are retained is not changing.

These hybrid techniques involving thresholding and integration techniques may generally be suitable for automatic image analysis (e. g., identifying locations of objects in an image). In particular, these techniques may be suitable for automatic image analysis of periodic or high density structures, such as high density arrays.

Light intensity characteristics of a spot in a current image may be used to weight spots in that image or in other images. Such weighing techniques may

sometimes be referred to as masking or filtering.

Illustrative steps involved in weighing are shown in FIG. 16. At step 168, an average intensity profile for objects that have been determined in an image may be determined. This gives an image of the intensity profile as a function of the average position of objects in a plurality of regions that were used in locating the objects. At step 170, the determined intensity profile may be applied in locating objects (e. g., applying profile to regions in integration techniques).

An average intensity profile may be determined using information from integration techniques. For example, as shown in FIG. 17a, integration techniques may have been applied to locate a plurality of regions (e. g., regions 172) that are determined to include spots. Regions 172 may each have approximately a same shape. Pixels that are approximately located in a same location in each region (e. g., each pixel that is in the upper left corner of each region) may be averaged to determine average intensity profile 173. The profile may indicate shape characteristics of the spots, such as whether the spots are doughnut-shaped, U-shaped, etc. Shape characteristics may be dependent on techniques used to place spots on a slide. FIG. 17b illustratively shows mask 171 that may be used in image analysis. Mask 171 may comprise weights that are associated with each

pixel position in mask 171. The values of the weights may vary (e. g., from 1 to 8) at different positions in mask 171 to appropriately enhance or weaken pixels in a portion of an image for which mask 171 is applied.

The intensity profile of objects or the normalized profile of objects may be used to mask or weigh pixels in a region. The mask may be used to enhance the intensity of pixels that belong to spots and weaken those that do not. In application to integration techniques, the profile may be used to weigh the integrated region by a shape function. For example, instead of simply performing integration on the pixels in a region of interest, a shape function that is based on the profile may be used to weigh the intensity of each pixel during integration. A list of integration regions that were determined using this pixel-by-pixel weighing technique may be more likely to include objects of interest at the top of the list. An integration technique may be applied again in combination with a filtering mask (e. g., a normalized profile) to the image that was used to determine the mask. If desired, a filtering mask may be applied in applying integration techniques to other images that contain objects or structures of objects that are similar to the objects or structures in the image used to form the mask.

Such masking techniques may be generally suitable for automated image analysis. In particular,

these techniques may be suitable for images having periodic or high density structures, such as high density arrays.

Thus, techniques for automatically locating objects in an image may be provided. Such techniques may be used in image analysis of objects in a variety of applications. For example, such techniques may be used to identify objects in a radar display, to analyze sonar patterns, to. identify objects in aerial photographs, to chart stars, to identify cancerous cells, to differentiate cells, to trace circuits, etc.

In some biological or biomedical applications, spots containing DNA materials, proteins, cell types, etc. may be placed on a slide using techniques such as by printing spots on the slide by dipping a printing pin in a desired material and striking the slide with the pin to leave a spot of the material on the slide. A plurality of pins may be operating (e. g., using robotics) in parallel to place spots in a grid at a plurality of grid points to form a high density array of spots on a slide. Each pin may be used to furnish a subgrid of a high density array (e. g., using one pin to fill a subgrid).

Points in a grid that were used to place a high density array of spots on a slide may primarily be discussed in the context of grid points. Slides may include points that may be evaluated to determine locations of spots on the slide. Such points, points

on a slide, may be primarily discussed in the context of the term points to differentiate points or a slide, slide points, from grid points.

Each grid point may be used to place a spot that contains a different material. Spots, which have been automatically located may be mapped to (e. g., matched with) grid points that were used to place the spots. After mapping, each spot may be indexed based on row and column of the spot in a high density spot array and based on the row and column of the printing pin that may have been used to print that spot.

Locations of grid points may be used to locate spots in the image. For example, after mapping, thresholding techniques may be applied to an area at the position of an empty grid point to find a missing spot.

Mapping may be performed based on the structure of the grid used to place the spots (e. g., the relationship of the grid point to each other). The structure of the grid may be determined based on spot pitch, pin pitch, and number of spot and pin rows and columns for the current high density array under analysis.

Illustrative steps involved in mapping spots to grid points are shown in FIG. 18. At step 174, areas in an image may be identified to include spots (e. g., by using thresholding techniques, integration techniques, etc.). At step 178, a structural relationship for grid points in a grid that was used to

fill a high density array of spots may be determined.

At step 180, spots may be mapped to appropriate grid points.

With reference to FIG. 19, grid 182 may be placed on image 184 (a part of which is shown) for spot mapping. Placing grid 182 on image 184 may involve selecting an origin for grid 182 on image 184. A best origin may be found by moving grid 182 within the bounds of image 184 to test possible origin pixels (e. g., from initial origin pixel 183).

A best origin may be determined based on light intensity of spots, distance between grid points and spots, etc. For example, with reference now to FIG. 20, grid 186, which may be part of a larger grid, may be placed on image 188, which may be part of larger image, at initial test origin pixel 187. Image 188 may include a plurality of spots. Grid 186 may include grid points 190. Areas that lie within a specific distance of each grid point 190 may be identified (e. g., a circle surrounding each grid point 190 with a radius having a specified length). Test pixels may be used to find a best origin for grid 186 based on maximizing intensity of spots that are within the specified distance from exchange of grid points 190.

Each spot may be assigned to a nearest grid point when a best origin has been determined. Extraneous spots may be ignored.

A best origin may be determined based on the distance between spots and grid points. Grid 186 may be moved based on minimizing distances between each one of grid points 190 and the spot assigned to that grid point.

If desired, mapping may be further adjusted pin-by-pin, subgrid-by-subgrid, etc. A best origin for each grid point may be determined by moving the location of the grid point to maximize total intensity in an area within a certain distance of the grid point.

If desired, a best origin for each gird point may be determined by moving the location of the grid point on the image to minimize the distance between the grid point and a spot that has been assigned to the grid point.

An actual spot pitch for spots in a high density spot array of an image may be determined.

Actual spot pitch may be determined to compensate for such things as image skew, slide rotation, rattle of printing pins, variable motion of printer, etc.

Illustrative steps involved in determining a printing grid structure are shown in FIG. 21. At step 14, a plurality of unit cell spot pitch vectors may be determined. For example, a plurality of vectors may be determined using plural pairs of nearest neighboring spots. The vectors may be approximately pointing in the same direction. At step 196, an actual unit cell spot pitch may be determined. The actual spot pitch

may be determined by averaging the plurality of unit cell spot pitch vectors. At step 198, a grid structure may be determined based on the actual spot pitch. The actual spot pitch may be used to determine the positional relationship of grid points to each other.

Illustrative steps involved in determining unit cell spot pitch vectors for determining actual spot pitch are shown in FIG. 22. At step 200, a unit cell spot pitch vector may be provided by determining a vector from a current spot to a nearest neighboring spot (e. g., the nearest neighboring spot to the right).

At step 202, the length of the vector may be determined to determine whether the vector meets a desired tolerance.

Tolerance for spot pitch vectors may be determined based on distance. For example, as shown in FIGS. 23a and 23b, a spot pitch vector may be selected to be used in determining an actual spot pitch when a nearest neighboring spot is within a distance of a predicted location for that spot. With reference now to FIG. 23a, current spot 209 may have nearest neighboring spot 206 that is to the right of current spot 204. Based on a predicted spot pitch, spot 206 may have been predicted to be centered on pixel 208. A particular distance tolerance for variation in location of a predicted spot location and an actual spot location may have been selected. For example, the center of spot 206 may have to be within a spot radius

of pixel 208. Unit spot pitch vector 210 may be used in determining an actual spot pitch based on the center of spot 206 being approximately within a spot radius of pixel 208. With reference now to FIG. 23b, unit cell spot pitch vector 212 may not be used based on spot 214 being approximately outside a desired distance from a predicted center for spot 214.

To obtain an actual horizontal spot pitch, a nearest neighboring spot to the right of each spot may be located. Vectors connecting pairs of spots (each spot connected to a nearest neighboring spot to the right) may be located. Vectors that meet a distance tolerance may be averaged to obtain an actual horizontal spot pitch. If desired, vectors that deviate beyond a particular tolerance in the vertical direction may be excluded from the calculation. The actual horizontal spot pitch may be written as ax i + ay j. Similarly, an actual vertical spot pitch vector may be obtained by averaging vectors between each spot and the nearest neighboring spot below. Vectors that do not meet a distance tolerance or vary beyond a particular tolerance in the horizontal direction may be excluded from the average. An actual vertical spot pitch may be written as bx i + by j.

Iterative techniques may be used to determine a spot pitch vector. For example, a determined spot pitch vector may be used to prime another determination of the spot pitch vector. A determined spot vector may

be used in a next iteration to set the tolerance used in determining which spot pitch vectors are averaged and which are discarded. If desired, iterations may continue until converging or until a maximum number is reached.

Pairing spots in determining unit cell spot pitch vectors may be determined based on which rows (or columns) spots are located. Illustrative steps involved in pairing spots based on row (or column) are shown in FIG. 24. At step 216, row and column locations of spots in a high density array in an image may be determined. The spots may be sorted based on row or column position. At step 218, pairs of spots for determining actual spot pitch may be determined, by eliminating pairs based on row (or column) positions of the spots (e. g., spots that are more than one row apart are not paired). If desired, spot pairs that have appropriate row (or column) criteria may be further evaluated based on a distance tolerance (as discussed above).

In some known spot printing techniques, a subgrid of spots may be printed in one strike of a printing head. The printing head may have a plurality of pins arranged in a subgrid. Illustrative steps involved in mapping spots to a subgrid that was used to place the spots (e. g., place the spots in one strike) are shown in FIG. 25. At step 220, grid points may be mapped to spots based on a spot pitch (e. g., an actual

spot pitch). At step 222, subgrids in the grid may be identified. At step 229, spots that have been mapped to subgrids may be determined. At step 226, a subgrid spot pitch may be determined for the subgrids based on the spots that are in the subgrids. At step 228, spots may be remapped to grid points based on spot pitches for the subgrids.

One known use of high density spot arrays may involve hybridization of DNA from at least two different sources, such as normal lung tissue and cancerous lung tissue on the same high density array.

DNA from each source may be tagged, for example, with a different fluorescent molecule so that differential expressions are observable through light intensity. An image may be generated from a slide for each fluorescent tag/tissue type on the slide. Analysis of expression may involve gathering data from approximately a same position in each slide.

Illustrative steps involved in analysis of expression of spots from two source materials are shown in FIGS. 26a and 26b. FIGS. 27a-27f illustratively show spot analysis based on steps of FIGS. 26a and 26b.

At step 230, a slide (e. g., slide 242) may be provided that may have a high density array of spots that includes materials from a plurality of sources (e. g., spots either include cancerous or noncancerous tissue with a different fluorescent tag being used for each tissue type). At step 232, a plurality of images

may be generated based on the slide, for example, one image (e. g., image 299) may be generated based on the characteristics of the fluorescent tag for one material tissue and another image (e. g., image 246) may be generated based on the characteristics of the fluorescent tag for the other material. Locations of spots in the images may be determined at step 232. At step 234, images (e. g., images 244 and 246) may be aligned to provide aligned images (e. g., image 248 and 259). To align images, one image may be selected as a reference image and the other image may be aligned to the reference image (e. g., using matrix transformation).

Images may be aligned using matrix transformation techniques. A reference image may be selected and other images of about the same size as the reference image may be aligned to the reference image using matrix transformation techniques. A transformation matrix may have the following form : Variables r and c may be row and column positions in pixels of an image. Subscript r may indicate reference image and subscript u may indicate unaligned image.

The terms a, b, c, d, e, and f may represent coefficients. Positions of spots in the images that may have been determined using, for example,

integration techniques, may be used to compute coefficients a, b, c, d, e, and f. A least squares process may be used to determine coefficients. The square of the distance between the actual position of a spot on an unaligned image (ru, cu) and aligned position (ru, cu where (ru*, Cu) is calculated with the transformation matrix using the position of the same spot on the reference image (rr, cr), may be the following : d2 = (r*u-ru)2 + (c*u-cu)2.

Substitution of the matrix transformation for (r u, cu) may give the following : a2r2r + c2r2r + abrrCr + 2cdrrCr + 2aerr + 2cfrr2arrru2CrrCu + b2C2r + d2cr2 + 2becr + 2dfc4 - 2bcrru - 2dcrcu - 2cru - 2fcu + e2 + f2 + r2u + c2u.

The sum of the square of the distance for all spots may be minimized in terms of the coefficients. Performing this minimization may give the following two sets of linear equations that may be used to obtain a, b, c, d, e, and f. and

The notation <x> refers to the averages of the quantity "x."Thus, <rr> may denote the average over all spots of the row position on the reference image. The term <rrCUz may denote the average over all spots of the row position on the reference image multiplied by the column position on the unaligned image for the same spot.

An aligned image may be determined when the matrix transformation coefficients (a, b, c, d, e, and f) that relate an unaligned image to the reference image have been determined. The aligned image may have approximately the same size as the reference image.

For each pixel in an aligned image, a corresponding position on the unaligned image may be determined. The intensity at the determined position on the unaligned image may be transferred to the corresponding position on the aligned image. Transferring intensities may involve interpolation of pixel intensities or direct transfer of intensities. Alignment techniques may be performed once per image. Alignment of the reference image may be excluded. If desired, alignment techniques, such as spot-by-spot alignment by minimization of a standard deviation of the logarithm

of the ratio of intensities, may be used or may be used after matrix transformation techniques.

At step 236, a composite image (e. g., image 252) may be determined. A composite image may be determined by combining intensities of pixels in each aligned image that are approximately in the same location. At step 238, spots in the composite image may be located (e. g., by using thresholding techniques, integration techniques, etc.). At step 240, aligned images (e. g., images 248 and 250) may be analyzed based on locations of spots that were determined in the composite image.

A composite image may have been formed and locations of spots in the image may be identified to guarantee that data from image analysis of the aligned images are from the same pixels in each image. Data about the spots in the aligned images may be generated to analyze the different root sources that were placed on the slides.

With reference now to FIG. 28, at step 300, image information may be obtained based on the techniques and systems discussed herein. Image information may be obtained to determine information about a new subject of concern. Image information may be obtained using techniques such as, thresholding, integration, masking, mapping, etc. Image information may include morphological properties, location (s), size, shape, spacing, etc. Image information may be

obtained for the new subject in a variety of technical fields. Image information may be obtained for high density arrays, radar images, target identification, machine movement control, differential expression of DNA, absolute expression of DNA, etc.

At step 302, image information may be applied to an appropriate database of information. The database may be appropriate for the technical field or appropriate for that type of subject. For example, the database may include information about known differential expressions of different cancers, known absolute expressions of DNA, known physical characteristics of different objects under radar, known physical characteristics of targets, etc. The database may include information that may be applied to the image information of the new subject.

At step 304, the new subject may be identified or a nature, quality, or characteristic of the new subject may be identified based on the image information being applied to the database information.

For example, the type of cancer may be identified, a birth defect may be identified (e. g., when using absolute expressions), a type of airplane may be identified, a shape of an airplane may be identified, a particular direction for machine movement may be identified, etc. The identification or identity information may be displayed for use in the particular technical field that is involved.

Examples of such applications may involve medical testing of patients. For example, cancerous and noncancerous cells may be extracted from patient.

The cells may be placed on a slide in a high density array of spots and hybridized to obtain differential expression of the cells. Image information about the spots may be obtained based on the techniques discussed herein. The image information may be applied to a database that includes information about differential expression characteristics of different types of cancer. The identify of the type of cancer may be provided based on the image and database information.

As discussed above, these techniques may be provided for other technical effects such as when using absolute expressions of DNA, using radar image information to identify objects, etc.

FIG. 29 presents a cross-section of a magnetic data storage medium 400 which can be encoded with a machine executable program that can be carried out by equipment such as equipment 20 of FIG. 1 to implement methods discussed in connection with FIGS. 2- 27. Medium 400 may be the storage device of equipment 20 of FIG. 2. Medium 400 can be floppy diskette or hard disk, having a suitable substrate 401, which may be conventional, and a suitable coating 402, which may be conventional, on one or both sides, containing magnetic domains (not visible) whose polarity or orientation can be altered magnetically.

Medium 400 may also have an opening (not shown) for receiving the spindle of a disk drive or other data storage device.

The magnetic domains of coating 402 of medium 400 are polarized or oriented so as to encode, in manner which may be conventional, a machine- executable program such as those described above in connection with FIGS. 2-28, for execution by equipment such as equipment 20 of FIG. 1.

FIG. 30 shows a cross-section of an optically-readable data storage medium 500 which also can be encoded with such a machine-executable program, which can be carried out by equipment such as equipment 100 of FIG. 1. Medium 500 can be a conventional compact disk read only memory (CD-ROM) or a rewritable medium such as a CD-R or CD-RW disk or a magneto-optical disk which is optically readable and magneto-optically writeable. Medium 500 preferably has a suitable substrate 501, which may be conventional, and a suitable coating 502, which may be conventional, usually on one side of substrate 501.

In the case of a CD-ROM, as is well known, coating 502 is reflective and is impressed with a plurality of pits 503 to encode the machine-executable program. The arrangement of pits is read by reflecting laser light off the surface of coating 502. A protective coating 504, which preferably is

substantially transparent, is provided on top of coating 502.

In the case of magneto-optical disk, as is well known, coating 502 has no pits 503, but has a plurality of magnetic domains whose polarity or orientation can be changed magnetically when heated above a certain temperature, as by a laser (not shown).

The orientation of the domains can be read by measuring the polarization of laser light reflected from coating 502. The arrangement of the domains encodes the program as described above.

Thus, spot analysis may be accomplished automatically by locating spots in high density array of spots, mapping spots to printing pins used to furnish high density arrays, determining quantitative characteristics of spots in a high density array, etc.

Such technique (e. g., thresholding, integration, mapping, filtering, etc.) may provide an appropriate balance between accuracy, speed of performance, complexity, processing demands, and storage requirements. With unlimited, processing speed and storage capability, highly complex techniques may be performed at high speeds to provide precise results.

The techniques discussed herein, however, have been determined to provide appropriate precision without undue complexity or without an inappropriate drain on processing or storage capabilities.

The foregoing is merely illustrative of the principles of this invention and various modifications can be made by those skilled in the art without departing from the scope and spirit of the invention.

Computer Program Listing Appendix align background. c #include"defs. h" void align-background (struct image-data *iml, struct image_data *im2, double * rot_angle, double * row shift, double * column_shift, double angle_range, double shift range, double angle-step, double shift step, int nbboxes, struct background box * bboxes) {double a, b, c, d, e, f, row frac, colfrac, row old, col old,

it, ib, angle, ratio, sd, rad, avel, ave2, ave, sum, sum2, best_angle, beste, best f, best_sd, best_ave, min_pixel, lastmax, best avel=0. 0, best ave2=0. 0, starte, start f, ende=0. 0, end_f=0. 0, start_angle, end_angle=0. 0 ; unsigned short int *new_data ;

int i, row, col, row-int, col_int, count=0, bbox, negative_pixels, step, angle_grid, shift_grid ; avel=0. 0 ; count=0 ; for (i=0 ; i< (iml->height*iml->width) ; i++) if (iml->data' [i] >0) avel+= (double) iml->data [i] ; count++ ; printf ("#image 1 average'I = %f\n", avel/ ( (double) count)) ; avel/= ( (double) count) ; ave2=0. 0 ; count=0 ;

for (i=0 ; i< (im2->height*im2->width) ; i++) { if (im2->data [i] >O) { ave2+= (double) im2->data [i] ; count++ ; printf ("#image 2 average I = %f\n", ave2/((double)count)) ; ave2/= (double) count ; best_sd=l. Oel4 ; best angle=rotangle [0] ; beste=rowshift [0] ; bestf=columnshift [0] ; best ave=-1. 0 ; last_max=-1.0e10 ; step=l ; shift_grid= (int) (2. 0*shiftrange/shiftstep) ; angle_grid= (int) (2. 0*angle_range/angle_step) ; while ((last_max<best_ave) && ( (fabs ((best_ave-last_max)/best_ave))>0.00001)) start_angle=rot_angle[0]-angle_range ; starte=rowshift [0]-shiftrange ; start_f=column_shift [0]-shiftrange ; lastmax=bestave ;

for (angle= (rotangle [0]-anglerange) ; angle<= (rotangle [ 0]+angle_range);angle+=angle_step) end_angle=angle ; rad=2. 0*MPI*angle/360. 0 ; a = cos (rad) ; b =-sin (rad) ; c =-b ; d = a ; printf ("#%f %f %f %f\n", a, b, c, d) ; for (e= (rowshift [0]-shift range) ; e< (row shift [0] +shift range) ;e|=shift_step) { ende=e ; for (f= (column_shift[0] -shift_range) ; f< (column_shift [0]+ shift-range) ;f+=shift_step) endf=f ; count=0 ; sum=0. 0 ; sum2=0. 0 ; avel=0. 0 ; ave2=0. 0 ; for (bbox=O ; bbox<nbboxes ; bbox++)

for (row=bboxes [bbox]. row ; row< (bboxes [bbox]. row+bboxes [bbox]. height) ; row++) j=row*iml [0]. width ; for (col=bboxes [bbox]. column ; col< (bboxes [bbox]. column+bboxes [bbox]. width) ; col++) { row_old= a*row + b*col + e ; col_old= c*row + d*col + f ; if ((row_old>=O. O) && (rowold<= ( (double) im2 [0]. height-1. 0)) && (col_old>=0.0) && (colold<= ( (double) im2 [0]. width-1. 0))) /* interpolate intensity */ col_int=((int) col_old) ; row_int=((int) row_old) ; i=rowint*im2 [0]. width + colin ; colfrac=colold-colint ; rowfrac=rowold-rowint ; if ((col_int+1) <im2 [0]. width) it= (1. 0-col frac) * ( (double) im2 [0]. data [i]) + col_frac*((double) im2 [0]. data [i+1]) ; else

it= ( (double) im2 [0]. data [i]) ; if ((row_int+1) <im2 [0]. height) if ((col_int+1) <im2 [0]. width) ib= (1. 0-col_frac) * ( (double) im2 [0]. data [i+im2 [0]. width]) + col_frac*((double) im2 [0]. data [i+im2 [0]. width+1]) ; else ib= ( (double) im2 [0]. data [i]) ; else { ib=it ; count++ ; ratio= ( (1. 0-row frac) *it + row frac*ib) * ( (double) iml->data [j+col]) ; avel+=iml->data [j+col] ; ave2+= ((1.0-row_frac) *it + rowfrac*ib) ; sum+=ratio ; sum2+=ratio*ratio ; /*else new_data[j+col] = ((unsigned short int) 0) ; */

sd=sqrt (sum2/ ( (double) count)- sum*sum/ ( (double) (count*count))) ; printf("%f %f %f %f %f\n", angle, e, f, sum/ (double) count, sd) ; if (sum>bestave) { best_angle=angle ; beste=e ; best_f=f ; bestave=sum ; bestsd=sd ; best_ave2=ave2/((double) count) ; best_avel=avel/((double) count) ; printf ("##%f %f %f %f %f\n", best_angle, best_e, best f, best ave, best sd) ; if ((best_angle ! =start angle) && (best_angle!=end_angle) && (best_e!=start_e) && (best_e!=end_e) && (best_f!=start_f) && (best_f!=end_f) )

printf ("&num &num narrowing grid\n") ; anglerange=anglestep*3. 0 ; shiftrange=shiftstep*3. 0 ; angle_step=angle_range/(double)angle_grid ; shift_step=shift_range/(double)shift_grid ; rotangle [0] =bestangle ; rowshift [0] =beste ; columnshift [0] =bestf ; e=beste ; f=bestf ; rad=2. 0*M_PI*best_angle/360. 0 ; a = cos (rad) ; b ='-sin (rad) ; c =-b ; d = a ; avel=bestavel ; ave2=bestave2 ; rot-angle [0] =bestangle ; rowshift [0] =beste ; columnshift [0] =bestf ; /* Now rotate one to two */ new_data= (unsigned short int *) malloc (sizeof (unsigned short int) * im1[0]. width * iml [0]. height) ;

if (newdata==NULL) {printf ("Failed malloc for new-data in align image... \n") ; exit (-1) ; negative pixels=0 ; min pixel=0. 0 ; for (row=0 ; row<iml [O]. height ; row++) {j=row*iml [0]. width ; for (col=0 ; col<iml [0]. width ; col++) row_old= a*row + b*col + e ; col_old= c*row + d*col + f ; if ((row_old>=0.0) && (row_old<=((double) im2 [0]. height-1. 0)) && (col_old>=0.0) && (col_old<=((double) im2 [0]. width-1. 0))) /* interpolate intensity */ col_int= ((int) col_old) ; row_int=((int) row_old) ; i=rowint*im2 [0]. width + col int ; colfrac=colold-colint ; rowfrac=row old-rowint ; _

if ((col_int+1) <im2 [0]. width) it= (1. 0-col_frac) * ( (double) im2 [0]. data [i]) + col_frac*((double) im2 [0]. data[i+1]) ; else it= ( (double) im2 [0]. data [i]) ; if ((row_int+1) <im2 [0]. height) {if ((col_int+1) <im2 [0]. width) ib= (1. 0-col_frac) * ( (double) im2 [0]. data [i+im2 [0]. width]) + col_frac*((double) im2 [0]. data [i+im2 [0]. width+1]) ; else ib= ( (double) im2 [0]. data [i]) ; else ib=it ; new_data[j+col]=((unsigned short int) fabs ( ( (1. 0-rowfrac) *it + rowfrac*ib)- (0. 7*ave2/avel) * ( (double) iml->data [j+col]))) ; if ( ( ( (1. 0-rowfrac) *it + rowfrac*ib)- (ave2/avel) * ((double)im1->data[j+col]))<0.0) negative_pixels++ ; if ( ( ( (1. 0-row-frac) *it + rowfrac*ib)- (ave2/avel) * ( (double) iml->data [j+col])) <minpixel) {

if (iml->data [j+col] <MAX_INTENSITY) min_pixel= ( ( (1. 0-rowfrac) *it + row frac*ib)- (ave2/avel) * ( (double) iml->data [j+col])) ; else new_data[j+col]=((junsigned short int) 0) ; } /* Free the old image data data */ free (im2 [0]. data) ; /* Assign new image */ im2 [0]. data=newdata ; /* Reset image size */ im2 [0]. width=im1 [0]. width ; im2 [0]. height=im1 [0]. height ; ave=0. 0 ; count=0 ; for (i=0 ; i< (im2->height*im2->width) ; i++) { if (im2->data [i] >0) ave+= (double) im2->data [i] ; count++ ;

printf ("#%i non-zero pixels\n", count) ; if (count) printf ("#image 2 average I = %f\n", ave/(count)); printf ("#minimum value = %f\n", min_pixel) ; printf ("&num oui negative pixels\n", negative pixels) ; align-images. c &num include"defs. h" int same-size (struct image_data **images, int numimages) {int m ; for (m=1 ; m<numimages ; m++) if ( (images [m] [O]. width !=images [0] [0]. width) # (images [m] [O]. height !=images [0] [0]. height)) return (O) ; return (1) ;

void align-image (struct image data *iml, struct image_data *im2, int interpolate) {double r1=0.0, r2=0. 0, cl=0. 0, c2=0. 0, rlcl=0. 0, rlr2=0. 0, rlc2=0. 0, clr2=0. 0, clc2=0. 0, ru2=0. 0, cl2=0. 0, a, b, c, d, e, f, denominator, hold, row frac, col-frac, row-old, col_old, it, ib ;

unsigned short int *new_data ; int i, il nb, row, col, row-int, col_int, count=0 ; if (im1[0].num_boxes !=im2 [0] .num_boxes) {printf ("Error, align-image cannot work if the number of boxes is not equal... \n") ; exit (-1) ; nb=iml [O]. numboxes ; /* Get averages */ for (i=O ; i<nb ; i++) if ((im1[0]. boxes [i]. boxtype==INGRID) && (im2 [0]. boxes [i]. boxtype==INGRID)) {rl=rl+ ((double) im1[0]. boxes [i]. box-row) ; r2=r2+ ( (double) im2 [0]. boxes [i]. box-row) ; cl=cl+ ((double) iml [O]. boxes [i]. box_column) ; c2=c2+ ((double) im2[0]. boxes [i]. box_column) ;

rlcl=rlcl+ ((double) iml [O]. boxes [i]. box-row) * ((double) im1[0]. boxes [i]. box-column) ; rlr2=rlr2+ ((double) iml [O]. boxes [i]. box-row) * ( (double) im2 [0]. boxes [i]. box-row) ; rlc2=rlc2+ ((double) im1[0]. boxes [i]. box-row) * ( (double) im2 [0]. boxes [i]. box_column) ; clr2=clr2+ ((double) im1[0]. boxes [i]. box_column) * ( (double) im2 [0]. boxes [i]. box-row) ; clc2=clc2+ ((double) im1[0]. boxes [i]. box column ? * ( (double) im2 [0]. boxes [i]. box_column) ; r1_2=r1_2+ ((double) im1[0]. boxes [i]. box-row) ((double) im1[0]. boxes [i]. box-row) ; cl2=cl2+ ( (double) iml [0]. boxes [i]. box_column) * ((double) im1[0]. boxes [i]. box_column) ; count++ ; rl=rl/ ( (double) count) ; r2=r2/ ( (double) count) ; cl=cl/ ( (double) count) ; c2=c2/((double count) ; rlcl=rlcl/ ( (double) count) ; rlr2=rlr2/ ( (double) count) ; r1c2=r1c2/((double) count) ; clr2=clr2/ ( (double) count) ;

clc2=clc2/ ( (double) count) ; rl-2=rl-2/((double) count) ; c1_2=c1_2/(double) count) ; hold=2*rl*cl*rlcl + rl2*cl2- (rlcl*rlcl + rl*rl*cl2 + cl*cl*rl2) ; if (hold ! =0. 0) denominator=1. 0/hold ; else printf("System of equations in align image is not linearly independent... \n") ; exit (-l) ; a= ( (r2*rlcl*cl + cl*rl*clr2 + rlr2*cl2)- (clr2*rlcl + cl2*rl*r2 + cl*rlr2*cl)) *denominator ; b= ( (rl*rlr2*cl + r2*rl*rlcl + rl2*clr2)- (rlcl*rlr2 + clr2*rl*rl + cl*rl2*r2)) *denominator ; e= ( (rl*rlcl*clr2 + cl*rlr2*rlcl + r2*rl2*cl2)- (rlcl*rlcl*r2 + c1_2*r1r2*r1 + c1r2*r1_2*c1)) *denominator ; c= ( (c2*rlcl*cl + cl*rl*clc2 + r1c2*c1_2) - (c1c2*r1c1 + cl2*rl*c2 + cl*rlc2*cl)) *denominator ; d= ((r1*r1c2*c1 + c2*rl*rlcl + r1_2*c1c2) - (rlcl*rlc2 + clc2*rl*rl + c1*r1_2*c2)) *denominator ;

f= ( (rl*rlcl*clc2 + cl*rlc2*rlcl + c2*rl2*cl2)- (rlcl*rlcl*c2 + cl2*rlc2*rl + clc2*rl2*cl)) *denominator ; printf ("a=%9. 6f b=%9. 6f e=%9. 6f\n", a, b, e) ; printf ("c=%9. 6f d=%9. 6f f=%9. 6f\n", c, d, f) ; /* Now rotate one to two */ new data= (unsigned short int *) malloc (sizeof (unsigned short int) * iml [O]. width * iml [0]. height) ; if (new_data==NULL) {printf ("Failed malloc for new-data in align_image... \n") ; exit (-l) ; if (interpolate==l) for (row=0 ; row<iml [0]. height ; row++) {j=row*iml [0]. width ; for (col=0 ; col<iml [O]. width ; col++) row_old= a*row + b*col + e ; col_old= c*row + d*col + f ; if ((row_old>=O. O) && (rowold<= ( (double) im2 [0]. height-1. 0)) &&

(colold>=0. 0) && (colold<= ( (double) im2 [0]. width-1. 0))) /* interpolate intensity */ col_int=((int) col_old) ; row_int=((int) row_old) ; i=rowint*im2 [0]. width + col-int ; colfrac=colold-colint ; _ rowfrac=rowold-rowint ; if ((col_int+1) <im2 [0]. width) it= (1. 0-col-frac) * ( (double) im2 [0]. data [i]) + col_frace*(double) im2 [0]. data [i+1]) ; else it= ( (double) im2 [0]. data [i]) ; if ((row_int+1) <im2 [0]. height) {if ((col_int+1) <im2 [0]./ width) ib= (1. 0-col_frac) * ( (double) im2 [0]. data [i+im2 [0]. width]) + col_frac*(double) im2 [0]. data [i+im2 [0]. width+1]) ; else ib= ( (double) im2 [0]. data [i]) ; else {ib=it ;

new_data[j+col]=((unsigned short int) ((1.0-row_frac) *it + rowfrac*ib)) ; else new_data[j+col]=((unsigned short int) 0) ; } if (interpolate==0) for (row=0 ; row<iml [0]. height ; row++) {j=row*iml [0]. width ; for (col=0 ; col<iml [O]. width ; col++) { row_old= a*row + b*col + e ; col_old= c*row + d*col + f ; if ((row_old>=0.0) && (row_old<=((double) im2 [0]. height-1. 0)) && (col_old>=0.0) && (col_old<=((double) im2 [0]. width-1. 0))).

/* take the closest pixel intensity */ col_int=((int) col_old) ; row_int=((int) row_old) ; i=rowint*im2 [0]. width + col-int ;

colfrac=colold-colint ; _<BR> rowfrac=rowold-rowint ; _ if ((col_frac<0. 5) && (row_frac<0. 5)) new data [j+col] =im2 [0]. data [i] ; if ((col_frac>=0.5) && (rowfrac<0. 5)) {if ((col_int+1) <im2 [0]. width) {new_data[j+col]=im2[0]. data [i+1] ; else {new_data[j+col]=im2[0]. data [i] ; if ((col_frac<0. 5) && (rowfrac>=0. 5)) if ((row_int+1) <im2 [0]. height) {new_data[j+col]=im2[0]. data [i+im2 [0]. width] ; else {new_data[j+col]=im2[0]. data [i] ; if ((col_frac>=0. 5) && (rowfrac>=0. 5)) {if(((col_int+1)<im2[0].width) ((row_int+1)<im2[0].height))

new_data[j+col]=im2[0]. data [i+im2 [0]. width+1] ; if (((col_int+1) >=im2 [0]. width) && ((row_int+1) <im2 [0]. height)) new_data[j+col]=im2[0]. data [i+im2 [0]. width] ; if (((col_int+1) <im2 [0]. width) && ((row_int+1) >=im2 [0]. height)) new_data[j+col]=im2[0].data[i+1] ; if(((col_int+1)>=im2[0].width) && ((row_int+1) >=im2 [0]. height)) new_data[j+col]=im2[0]. data [i] ; } else new_data[j+col]=((unsigned short int) 0) ; } /* Free the old image data data */ free (im2 [0]. data) ; /* Assign new image */ im2 [0]. data=newdata ; /* Reset image size */ im2 [0]. width=iml [0]. width ;

im2 [0]. height=im1[0]. height ; void align images (struct image data **images, int numimages, struct parameters *all_params) {int m ; for (m= (numimages-l) ; m> (-l) ; m--) find-array (images [m], all_params) ; for (m=l ; m<num_images ; m++) align-image (images [O], images [m], all_params->printer_info. do-interpolate) ; background. c t #include"defs. h" void get_background_pixels (struct image data * image, struct background_params *params, struct box * this_box, int * numpixels, int * pixels)

int pixel, my_row, my col, row, col, start-row, start_col, end-row, end-col, outer_radius, h, w, background-width ; w=image->width ; h=image->height ; outer-radius = params->backgroundradius ; background-width = params->backgroundframewidth ; my_row = thisbox->boxrow ; my_col = thisbox->boxcolumn ; if (backgroundwidth>=outerradius) {printf ("Something is wrong in background calculation : background frame width bigger than region width\n") ; exit (-l) ;

if (params->mask_flag==1) get_mask_pixels (image, my_row, my_col, params->maskwidth, params->mask, num_pixels, pixels) ; else num_pixels[0] = 0 ; /*top*/ start-row = my row-outer radius ; if (start_row<0) start_row=0; start col = my col-outer radius ; if (startcol<0) startcol=0 ; end-row = startrow+backgroundwidth ; if (endrow>h) endrow = h ; end-col = my_col_outer_radius; if (endcol>w) endcol = w ; for (row=startrow ; row<endrow ; row++) for (col=startcol ; col<end col ; col++) { pixel=row*w+col ; bg_pixels[num_pixels [0]} =pixel ;

numpixels [0] ++ ; /*bottom*/ end row = my row+outer radius ; if (endrow>h) endrow = h ; start-row = end_row - background_width ; if (startrow<0) startrow = 0 ; for (row=startrow ; row<end_row ; row++) for (col=start_col ; col<endcol ; col++) pixel=row*w+col ; bg_pixels [num_pixels[0]] pixel ; num_pixels[0]++ ; } /*left*/ start_row = my_row-outer_radius+background_width; if (start_row<0) start_row=0 ; end-row = my_row+outer_radius-background_width ; if (endrow>h) endrow = h ;

end-col = startcol+backgroundwidth ; if (endcol>w) endcol = w ; for (row=startrow ; row<endrow ; row++) for (col=startcol ; col<endcol ; col++) pixel=row*w+col ; bgpixels [numpixels [0]] =pixel ; num_pixels [0] ++ ; } /*right*/ end_col = my_col+outer_radius ; if (end_col>w) end_col = w ; start col = end_col-background_width ; if (start_col<0) start_col=0 ; for (riow=start_row ; row<end_row ; row++) for (col=start_col ; col<end_col ; col++) pixel=row*w+col ; bg_pixels [num_pixels[0]] = pixel ; num_pixels[0]++ ; }

void compute local background (struct image_data * image, struct background_params * params, struct box * this box, struct overlap * oimage, struct statistics * stats) int pixel, outer-radius, background-area, * bgpixels ; unsigned short int *bg_list, *data ; data=image->data ; outerradius = params->backgroundradius ; if (params->mask-flag==l) {bg_pixels=(int *) malloc (params->maskwidth*params->maskwidth*sizeof (int )) ; bg-list= (unsigned short int *) malloc (params->mask_width*params->mask_width*sizeoif (uns igned short int)) ; if ((bg_pixels==NULL) # (bg_list==NULL)) {printf ("Failed malloc for bg_pixels or bg_list in compute-local background... \n") ;

exit (-l) ; get mask pixels (image, this_box->box_row, <BR> <BR> <BR> <BR> thisbox->boxcolumn,<BR> <BR> <BR> <BR> params->maskwidth,<BR> <BR> <BR> <BR> <BR> params->mask, &backgroundarea, pixels) ; if (oimage ! =NULL) if ( (oimage->width==image->width) && (oimage->height==image->height)) filterlistbypixelattribute (oimage, &bg_pixels, &backgroundarea, SPOTPIXEL) ; get mask pixels-intensities (image, <BR> <BR> <BR> thisbox->boxrow,<BR> <BR> <BR> <BR> <BR> thisbox->boxcolumn,<BR> <BR> <BR> <BR> params->mask width, params->mask, background-area, pixels, list) ; } else {pixels= (int *) malloc ((2*outer_radius+1) * (2*outer radius+1) *sizeof (int )) ;

list= (unsigned short int *) malloc ((2*outer_radius+1)*(2*outer_radius+1) *sizeof (uns igned short int)) ; if ((bg_pixels==NULL) # (bg_list==NULL)) {printf ("Failed malloc for Npixels or bg_list in computelocalbackground... \n") ; exit (-l) ; get background pixels (image, params, this box, &backgroundarea, bgpixels) ; if (oimage ! =NULL) if ( (oimage->width==image->width) &&<BR> (oimage->height==image->height))<BR> filterlistbypixelattribute (oimage, &bgpixels, &backgroundarea, SPOTPIXEL) ; for (pixel=0 ; pixel<backgroundarea ; pixel++) bg_list[pixel]=data[bg_pixels[ixel]] ; } get-list-statistics (bglist, backgroundarea, stats) ; free (list) ; free (pixels) ;

void compute-local background common (struct image data * image, struct background_params * params, struct box * this_box, struct overlap * oimage, struct statistics * stats) int pixel, outer-radius, background-area, * bg_pixels ; unsigned short int *bg_list, *data ; data=image->data ; outer-radius = params->backgroundradius ; if (oimage ! =NULL) {if((oimage->width==image->width) && (oimage->height==image->height)) {if (params->mask_flag==1) {pixels= (int *) malloc (params->maskwidth*params->maskwidth*sizeof (int )) i bg_list= (unsigned short int *) malloc (params->maskwidth*params->maskwidth*sizeof (uns igned short int)) ;

if ( pixels==NULL) # (bg_list==NULL)) {printf ("Failed malloc for bgpixels or bglist in compute_local_background,... \n") ; exit (-l) ; <BR> <BR> <BR> <BR> <BR> <BR> getmaskpixels (image, thisbox->boxrow,<BR> <BR> <BR> <BR> <BR> <BR> thisbox->boxcolumn, params->maskwidth, params->mask, &backgroundarea, bgpixels) ; Eilterlistbypixelattribute (oimage, &bg_pixels, &background_area, )SPOT_PIXEL#SATURATED_PIXEL) ); get_mask_pixels_intensities (image, thisbox->boxrow, this_box->box_column, params->maskwidth, params->mask, background-area, pixels, bglist) ; } else {pixels= (int *) malloc ((2*outer_radius+1) * (2*outer radius+1) *sizeof (int t ) bg_list= (unsigned short int *) malloc ((2*outer_radius+1) * (2*outer radius+1) *sizeof (uns igned short int)) ; if ((bg_pixels==NULL) # (bg_list==NULL))

{printf ("Failed malloc for bg_pixels or bg_list in compute-local background... \n") ; exit (-l) ; getbackgroundpixels (image, params, this box, &backgroundarea, bgpixels) ; filterlistbypixelattribute (oimage, &bg_pixels, &backgriound_area, (SPOT_PIXEL#SATURATED_PIXEL)) ; for (pixel=0 ; pixel<backgroundarea ; pixel++) bg_list [pixel]=data[bg_pixels[pixel]] ; get-list-statistics (list, background-area, stats) ; free (bglist) ; free (pixels) ; else printf ("Size of the overlap image does not match the image... \n") ; else printf ("Where is the overlap image ? \n") ;

void compute local background all (struct image data * image, struct background, params * params, struct overlap * oimage) int box ; for (box=0 ; box<image->numboxes ; box++) compute_local_background (image, params, &image->boxes [box], oimage, &image->boxes [box]. background) ; create-boxes. c &num include"defs. h" void create_box (struct image data * image, int my row, int my-col, struct integration_params * iparams, struct integration params * iparams_small, struct background params * bparams, struct box * b) {b [0]. boxrow=myrow ; b [OJ. boxcolumn=my col ; /* get the integrated intensity */

integrate region (image, iparams, my row, my col, &b->box) ; integrate_region (image, iparams_small, my_row, mycol, &b->smallbox) ; /* get the local background for this box */ compute_local_background (image, bparams, b, NULL, &b->background) ; /* set the spot type */ b [O]. boxtype=NOTINGRID ; b [0]. spot. pixel_positions=NULL ; b->numspots=0 ; /*set some pointers to NULL*/ b->reference=NULL ; b->wrtreference=NULL ; b->common=NULL ; void create_boxes (int *box_list, int numboxes, struct image-data * image, struct integration_params * iparams, struct integration_params * iparams_small, struct background_params * bparams) {struct box *boxes ; int i,

row, col ; boxes = (struct box *) malloc ((num_boxes) *sizeof (struct box)) ; if (boxes==NULL) {printf ("failed to allocate memory in create_structs\n") ; exit (l) ; for (i=O ; i<numboxes ; i++) {row=boxlist [i]/ (image->width) ; col=box-list [i]%(image->width) ; create-box (image, row, col, iparams, iparams_small, . bparams, &boxes [i]) ; /* copy the box info into the image structure */ image->numboxes = numboxes ; image->boxes = boxes ; defs. h #include"stdio. h" #include"stdlib. h"

#include "math.h" &num include. 1'string. h" #include"errno. h" #include <ctype. h> #ifndef EXPRESS ARRAY VERSION #define EXPRESS_ARRAY_VERSION "0.771" #endif /*Deal with windows lack of pagesize function*/ #ifdef MSVC #define getpagesize()B 4096 #else &num include"unistd. h" #endif &num include"jpeglib. h" &num include"tiffio. h" #include"setjmp. h" #include"structure. h" #ifndef MPI #define MPI 3. 14159265358979323846 #endif /* about boxes types */ #define IN GRID 1 #define NOIT_IN_GRID 2

/* about spot types */ #define REGULAR 0 #define POSITIVE 1 #define NEGATIVE 2 #define EMPTY 3 #define MISSING 4 #define APPARITION 5 #define FLOOD 6 /* about pixels */ #define PIXEL TYPES 6 #define INSIDE-1 #define OUTSIDE-2 #define TOO LOW-4 #define TOO_HIGH -8 #define EDGE-16 #define UNIDENTIFIED-32 /* furcation types */ #define SIMPLE 1 #define HOLEFILL 2 #define EDGEREJECT 3 #define EDGEREJECTHOLEFILL 4 /* intensity information */ #define MAXINTENSITY 65535 #define RATIOMAX DBLMAX

#ifdef DBLMAX #else #define DBLMAX 1. 797693e+308 #endif #ifdef DOS #define SLASHCHAR'' #define SLASHSTRING"\\" #else #define SLASHCHAR'/' #define SLASHSTRING"/" #endif /* about pixels, do not change these without also making necessary alterations to get and set-pixel attributes */ #define EMPTY PIXEL 0 #define SPOT PIXEL 1 #define BACKGROUND PIXEL 2 #define REGION PIXEL 4 #define SPOT PERIMETER PIXEL 8 #define REGION PERIMETER PIXEL 16 #define SATURATED-PIXEL 32 Integrated * integrate-regions (struct image data * data, struct integration_params * iparams) ;

Integrated * integrate_regions_rectangle_fast (unsigned short int * d, int w, int h, int a, int b) ; void integrate region (struct image data * image, struct integration_params * iparams, int row, int col, struct statistics * stats) ; void create_boxes (int *box_list, int numboxes, struct image_data * image, struct integration params * iparams, struct integration_paramks * iparams_small, struct background_params * bparams) ; void createbox (struct image data * image, int row, int col, struct integration params * iparams, struct integration_params * iparams_small, struct background_params * bparams, struct box * b) ;

void trifurcate (int r, int c, int w, int h, int *s, int sn, int type) ; int find-spots (int w, int h, unsigned short int * d, int ** s, int bl, int bh, int furcation-type) ; int find spots-simple (int w, int h, unsigned short int *d, int *s, unsigned short int bl, unsigned short int bh) ; int find-spots edgereject holefill (int w, int h, unsigned short int *d, int *s,

unsigned short int bl, unsigned short int bh) ; int find spots holefill (int w, int h, unsigned short int *d, int *s, unsigned short int bl, unsigned short int bh) ; int find spots edgereject (int w, int h, unsigned short int *d, int *s, unsigned short int bl, unsigned short int bh) ; void crop_image_data (struct image-data *our-image, struct spot_finding_params *sparams) ; void get_largest_spot_statistics (struct image data *image, struct box * b, struct spot_finding_params *params) ;

void get_largest_spot_perimeter (int * perimeter_pixels, struct image data *image, struct box * my box, struct spot_finding_params *params) ; void compute_local_bvackground-all (struct image data * image, struct background_params * params, struct overlap * oimage) ; void compute-local background (struct image data * image, struct backgriound_params * params, struct box * this_box, struct overlap * oimage, struct statistics * stats) ; void computelocalbackgroundcommon (struct image_data * image, struct background_params * params, struct box * this box, struct overlap * oimage, struct statistics * stats) ; void draw-grid (struct printer * p, struct image data * image) ;

int draw_integration_regions (struct image data * image, struct integration params * iparams, struct printer * p) ; void draw_local_background_regions(struct image_data * image, struct background_params * bparams, struct printer * p) ; void draw-box (unsigned short int *data, int w, int h, int r-int, int r, int c) ; void draw_thick_box (struct image-data * image, int center_pixel, int outsider, int width) ; void writetiffjpeg (struct image data * image, int quality, char *output path) ; void write-tiff-zip (struct image-data * image, char *output_path) ;

void write_jpeg (struct image data * image, int quality, char *output path) ; double quality (struct box * s, struct quality_params *. qparams) ; void improve-quality (struct image-data * image, struct parameters * all params) ; int remove overlapping boxes (struct box *s, int n, struct printer *p, struct quality_params * qparams) ; void read_printer_info (struct printer *print-info, char * printer_file_name) ; void set_parameter_defaults (char *fname, struct parameters * all params) ; struct image data *read image (char *fname) ; int write_ppm (struct image_data *our_image, char *output_path) ; struct image_data *read_ppm (char *fname) ;

struct image_data *readtiff (char *fname) ; void hsort (void *va, int *p, , int n, int size, int (*compare) (const void *, const void *)) ; void double-hsort (double *va, int *p, int n) ; void qsort-double (double *va, int *p, int n) ; void qsort_integrated (Integrated *va, int *p, int n) ; void qsortunsignedshortint (unsigned short int *va, int *p, int n) ; int double-sort-compare (const void *c, const void *d) ; int pixel-sort compare (const void *c,

const void *d) ; int data_sort_compare (const void *c, const void *d) ; void output image (struct image data * image, struct output_image_params * oparams) ; void outputintegratedimage (struct image-data * image, struct output_image_params * oparams) ; void find boxes (struct image_data *our_image, struct parameters *our_params) ; void find-boxes-fast (struct imagedata *our image, struct parameters *our_params) ; void claim intensity (struct image data *our-image, struct injtegration_params *iparams, int box) ; int inspect box (struct image_data *our_image, struct parameters *our_params, int row, int col) ;

void free-image (struct image data * image) ; struct image data *sum images (struct image data * images [], int numimages, char *file name stub) ; void parameter-check (struct image-data * image, struct parameters * all params) ; Integrated * integrate regions mask (unsigned short int *data, int w, int h, int width, double *mask) ; void integrate region mask (struct image-data * image, int row, int col, int width, double * mask, struct statistics * stats) ; void draw_region_mask (struct image-data * image, int row, int col, int width, double * mask) ; int getspotnumber (int pr,

int pc, int sr, int sc, struct printer *p) ; void getxyfromspotandpin (double hp, double kp, double hs, double ks, struct printer *p, double *x, double *y) ; void get xyfromspotnumber (int n, struct printer *p, double *x, double *y) ; void get_spotandpinfromnumber (int n, struct printer *p, int *pr, int *pc, int *sr, int *sc) ; int get pin number-from spot number (int n, struct printer *p) ;

void map-spots (struct image_data *our_image, struct map_spots_params *m, struct printer *p) ; void createmapimage (struct map_image *mi, struct map_spots_params *m, struct printer *p) ; void map_image_remove_missing (struct map-image *mi, struct printer *p) ; void free_map_image (struct map-image *mi) ; double map-intensity function (struct box *b) ; int get_spot_number_from_map_image (struct map-image *mi, struct box *b, int row-offset, int col_offset) ; void map_coarse (struct image data *our image, struct map-image *mi, struct printer *p, int inc, int debug) ; void map_fine (struct image_data *our_image,

struct map_image *mi, struct printer *p, int inc, int range-row, int range column, int debug) ; void map_pin_by_pin (struct image-data *our_image, struct map-image *mi, struct printer *p, int inc, int range_row, int range column, int debug) ; void map distance minimization (struct image-data *our-image, struct map_image *mi, struct printer *p, int inc, int range_row, int range column, int debug) ; void map_assign (struct image_data *our_image, struct map_image *mi, struct printer *p, int debug,

int snap_negatives) ; int find angles-compare xbar (const void *c, const void *d) ; int find angles compareybar (const void *c, const void *d) ; void find-angles (struct box *b, int n, struct findanglesparams *fa, struct printer *p) ; void fillinemptyboxes (struct image data * image, struct printer * p, struct integration_params * iparams, struct integration_params* iparams_small, struct background_params * bparams, struct spot_finding_params * sfparams) ; void transferspotstogrid (struct image-data * image, struct printer *p) ; void write-data (int image, int num_images, struct image data **the images, struct printer *p,

struct output data * f, char *output_path) ; void multiple_image_get_largest_spot_statistics (struct image_data, *comp_image, struct image_data **mult_image, int numimages, int boxnum, struct spot_finding_params *params) ; void multi_image_create_boxes (struct image data *comp_image, struct image-data **mult-image, int numimages, struct integration_params *iparams, struct integration_params *iparams_small, struct background_params *bparams) ; void multiimagecropimagedata (struct image data *comp_image,

struct image-data **mult-image, int numimages, struct spot_finding_params *params) ; void read parameters (struct parameters *p, char *fname) ; void get_integration_mask (struct integration params * iparams) ; void get_background_mask (struct background_params * bparams) ; void get-list-statistics (unsigned short int * list, int n, struct statistics *s) ; void get_integration_info (struct integration params * iparams) ; int write_multi_image_ppm (struct image-data *our-image [], int num_images, char *output path) ; void align_images (struct image data **images, int numimages, struct parameters *all_params) ;

void align-image (struct image-data *iml, struct image data *im2, int interpolate) ; int same-size (struct image data **images, int num_images ; int writemultiimageppm (struct image data *ourimage [], int numimages, char *output-path) ; void getdliststatistics (double * list, int n, struct statistics *s) ; void getdliststatisticsfast (double * list, int n, struct statistics *s) ; void draw-info (struct image-data * image, struct parameters * all-params, struct overlap *oimage) ; void int egrate_boxes (struct image-data * image, struct integration params * iparams) ; void find-array (struct image data * image, struct parameters * all_params) ; void findarraymulti (struct image-data * sum, struct image_data * images [],

int num-images, struct parameters * all_params) ; void credits () ; void check_command_line (int argc, char *argv []) ; void get_largest_spot_average_position (struct image data *image, struct box * b, struct spot_finding_params *params) ; void get_largest_spot_average_position (struct image data *image, struct box * b, struct spot_finding_params *params) ; void threshold-image (struct image_data *image, unsigned short int bl, unsigned short int bh) ; void findanglespinbypin (struct image-data *our_image, struct find_angles_params *fa, struct map_spots_params *m, struct printer *p) ;

void multiple_image_get_largest_spot_statistics_shift(struct image_data *comp_image, struct image_data **mult-image, int numimages, int boxnum, struct crop_image_data_params *crop_params) ; void multi_image_crop_image_data_shift (struct image_data *comp-image, struct image data **mult_image, int numimages, struct crop_image_data_params *params) ; void print output, data-line (int pr, int pc, int sr, int sc, struct box *b, struct printer *p, struct output data * flags, FILE *f, int is_ref) ; void crop_region (int row, int col, int w,

int h, unsigned short int * d, int * crop_w, int * crop h, , unsigned short int ** crop d, int * rs, int * cs, int * re, int * ce, struct spot_finding_params * sp) ; void create_overlap_image (struct overlap *oimage, struct image data *image, struct spot_finding_params *sfparams, struct background_params *bgparams, struct integration params *iparams, struct printer *pparams) ; void get_largest_spot_pixels (struct image data *image, struct box * b, struct spot_finding_params *params) ; void linear regression (struct image data *composite, struct image data *im ref, struct image data *im, int box) ;

void readspottypefile (struct printer *p) ; int writeppmascii (struct image_data *our_image, char *output-path) ; void align background (struct image-data *iml, struct image data *im2, double * rot_angle, double * row-shift, double * column_shift, double angle_range, double shift_range, double angle-step, double shift-step, int nbboxes, struct background-box * bboxes) ; unsigned short int set_threshold (double ibb, double isb, double area_bb, double areas, double area-spot, double fraction) ; void get mask pixels, intensities (struct image_data * image, int row, int col,

int mask-width, double * mask, int num_pixels, int * mask-pixels, unsigned short int * mask_pixel_intensities) ; void get mask-pixels (struct image data * image, int row, int col, int mask-width, double * mask, int * numpixels, int * mask pixels) ; void getbackgroundpixels (struct image_data * image, struct background_params *params, struct box * this_box, int * numpixels, int * pixels) ; void get_region_pixels (struct image-data * image, struct integration_params * iparams, int row, int col, int * num_pixels, int * pixel positions) ; void set_pixelk_attributes (char * pixel, char additional-attributes) ;

int test-Pixel-attributes (char pixel, char test_ttributes) ; void filterlistbyjpixelattribute (struct overlap * oimage, int ** pixel_positions, int * numpixels, char attributes) ; void integrateregion common (struct image data * image, struct integration, params * iparams, int row, int col, struct statistics * stats, struct overlap *oimage) ; void spot_statistics_common (struct image data * image, struct image data * refimage, int * pixel positions, int num_pixels, struct overlap * oimage, struct statistics * stats, struct statistics * ratio_stats)_ ; int writecolorpverlapppm (struct image data * our-image, struct overlap * oimage, char * output-path) ; void setintensitybypixelattribute (struct overlap * oimage,

int * pixel_positions, unsigned short int * pixel-intensities, int numpixels, char attributes, unsigned short int intensity) ; void add_saturation_to_overlap (struct overlap * oimage, struct image-data * image) ; void getinternalwidthandheight (struct map-image *mi) ; char * change-ext (char * string, char * ext) ; char * change-path (char * file_name, char * new-path) ; char * add-ext (char * string, char * ext) ; char * get-new-file-name (char * string, char * newpath, char * ext) ; int count_strstr (char * string, char * sub_string) ; char * goto n-strstr (char * string, int n, char * sub-string) ; void readspottypesgeneric (struct printer *p, FILE * f) ; void read gene-id generic (struct printer *p, FILE * f) ; void setgeneidgeneric (int pr, int pc, int sr, int sc, char *gene_id, struct printer * p) ; void read_gene_id_corning (struct printer *p, FILE * f) ;

void remove-attributes (struct overlap * oimage, char attributes) ; void unsetpixelattributes (char * pixel, char attributes) ; void pairwise_spot_statistics (struct image data *composite, struct image_data *im_ref, struct image-data *im, int box) ; draw boxes. c #include"defs. h" void draw perimeter new (struct image data *im, struct overlap *oimage) int i, n ; if ((im->width==oimage->width) && (im->height==oimage->height)) n=im->width*im->height ; for (i=0 ; i<n ; i++) if (test_pixel-attributes (oimage->image [i], SPOT_PERIMETER_PIXEL) !=0)

im->data [i] =MAX_INTENSITY ; void draw_background_new (struct image data *im, struct overlap *oimage) int i, n ; if ( (im->width==oimage->width) && (im->height==oimage->height)) n=im->width*im->height ; for (i=0 ; i<n ; i++) if ( (test pixel attributes (oimage->image [i], BACKGROUND PIXEL) ! =0) && (testpixelattributes (oimage->image [i], SPOT PIXEL) ==0)) im->data [i] =MAXINTENSITY ; void draw integration'regions new (struct image data *im, struct overlap *oimage) {int i, n ;

if ( (im->width==oimage->width) && (im->height==oimage->height)) { n=im->width*im->height ; for (i=0 ; i<n ; i++) if (test-pixel-attributes (oimage->image [i], REGION-PERIMETER-PIXEL) 1=0) im->data [i] =MAXINTENSITY ; void draw-info (struct image-data * image, struct parameters * all_params, struct overlap *oimage) struct image data dummy ; int pixel ; /*draw spot and region info to a dummy image and write out an image file*/ memcpy (&dummy, image, sizeof (struct image_data)) ; dummy. data= (unsigned short int *) malloc (sizeof (unsigned short int) *image->width*image->height) ; if (dummy. data==NULL) {printf ("failed malloc for output image in wspots. c\n") ; exit (-l) ;

} for (pixel=0 ; pixel< (image->width*image->height) ; pixel++) dummy. data [pixel]=image->data [pixel] ; printf ("perimeter-flag = %i\n", allparams->outputimage. perimeterflag) ; if (all params->output_image. perimeter-flag==l) /*draw_perimeter (&dummy, &all_params->draw_perimeter, &all_Params->printer_info) ; */ drawperimeternew (&dummy, oimage) ; if (allparams->outputimage. regionflag==l) /*draw_integration_regions (&dummy, &allparams->integrationout, &allparams->printerinfo) ; */ drawintegrationregionsnew (&dummy, oimage) ; if (allparams->outputimage. grid_flag==1) drawgrid (&allparams->printerinfo, &dummy) ; #ifdef WET DOT if (all_parmas->output_image.background_flag==1) /*draw_local_background_regions (&dummy, &allparams->background, &allparams->printerinfo) ; */ draw_background_new (&dummy, oimage) ;

#else if (allparams->outputimage. backgroundflag==l) /*draw local background regions (&dummy, &all_params->background, &allparams->printerinfo) ; */ draw background new (&dummy, oimage) ; #endif /* This is for debugging after calling find_boxes... for (pixel=0 ; pixel<dummy. numboxes ; pixel++) draw-thick-box (&dummy, dummy. width*dummy. boxes [pixel]. boxrow+dummy. boxes [pixe l]. box_column, 15, 2) ; */ output_image (&dummy, &all_params->output_image) ; free (dummy. data) ; void draw grid (struct printer * p, struct image data * image) int pin row, pin-column, spot row, spot-column, row, column, pn, c ; double x, y ; int w, h ;

unsigned short int * data ; w = image->width ; h = image->height ; data = image->data ; for (pin_row=0 ; pinrow<p->pinspercolumn ; pinrow++) for (pincolumn=0 ; pincolumn<p->pinsperrow ; pincolumn+ +) for (spot_row=O ; spot_row<p->spots_per_column ; spot_row++) for (spot column=0 ; spot_column<p->spots_per_row ; spot-col umn++) {pn=pin_row*(p[0].pins_per_row)+pin_column ; get_xyfromspotandpin (((doulble) pin_coliumn), ((double) pin_row), ((double) spot_column), ( (double) spot row), p, &x, &y) ; row= ( (int) (y+0. 5)) + p [0]. rowoffsets [pn] ; column= ( (int) (x+0. 5)) + p [0]. column_offsets [pn] ; if ((row>0) && (column>0) && (row< (h-1)) && (column< (w-l))) {c=row*w+column ;

data [c] =MAXINTENSITY ; data [c+l] =MAXINTENSITY ; data [c-l] =MAX_INTENSITY ; data [c+w] =MAXINTENSITY ; data [c-w] =MAX-INTENSITY ; data [C-W-1]=0 ; data [c-w+l] =0 ; data [C+W-1] =0 ; data [C+W+1]=0 ; int draw_integration_regions (struct image data * image, struct integration. params * iparams, struct printer * p) /* local variables */ int numgood=0, box ; /* defines for copying input parameters to local variables */ int w, h, r-int, numboxes, spotnum ;

struct box * boxes ; unsigned short int * data ; /* copy to local */ w = image->width ; h = image->height ; data = image->data ; boxes = image->boxes ; numboxes = image->numboxes ; r-int = iparams->integrationradius ; for (box=0 ; box<numboxes ; box++) if (boxes [box]. boxtype==INGRID) spotnum=getspotnumber (boxes [box]. pin_row, boxes [box]. pin_column, boxes [box]. spot_row, boxes [box]. spotcolumn, p) ; #ifdef WET DOT if (p->spot_type [spot_num]==EMPTY) #else if ((p->spot type [spot_num]==REGULAR) # (p->spot_type [spo t_num]==POSITIVE) # (p->spot_type [spot_num]==NEGATIVE)) #endif numgood++ ;

if (iparams->maskflag==l) draw_rgion_mask(image, boxes [box]. boxrow, boxes [box].box_column, iparams->maskwidth, iparams->perimetermask) ; else draw-box(data, w, h, r_int, boxes [box]. boxrow, boxes [box]. boxcolumn) ; return (num good) ; void draw-box (unsigned short int *data, int w, int h, int r-int, int r, int c)

int rs, re, cs, ce, row, col ; rs=r-rint ; if (rs<0) rs=0 ; re=r+rint+l ; if (re>h) re=h ; cs=c-rint ; if (cs<0) cs=O ; ce=c+r_int+1 ; if (ce>w) ce=w ; /* Top and bottom */ for (col=cs ; col<ce ; col++) {data [rs*w+col] =0 ; data [(rs+1) *w+col] =MAXINTENSITY ; data [(re-1) *w+col] =0 ; data [ (re-2) *w+col] =MAXINTENSITY ; /* left and right */ for (row=rs+l ; row< (re-1) ; row++) {data [row*w+cs] =0 ;

data [row*w+cs+l] =MAXINTENSITY ; data [row*w+ce-l] =0 ; data [row*w+ce-2] =MAXINTENSITY ; } void draw_local_background_regions (struct image data * image, struct background params * bparams, struct printer * p) /* local variables */ int box ; int center_pixel ; /* defines for copying input parameters to local variables */ int w, h, outsider, width, numboxes, spot num ; struct box * boxes ; unsigned short int * data ; /* copies of passed variables */ w = image->width ; h = image->height ;

data = image->data ; boxes = image->boxes ; numboxes = image->numboxes ; outsider = bparams->background radius ; width = bparams->backgroundframewidth ; if (width==0) return ; if (bparams->mask_flag==1) for (box=0 ; box<numboxes ; box++) &num ifdef WET DOT spot_num=get_spot_number (boxes [box]. pin_row, boxes [box]. pin_column, boxes [box]. spot_row, boxes [box]. spot-column, p) ; if ((boxes [box].box_type==NOT_IN_GRID) && (p->spot_type [sp otnum] ! =EMPTY)) draw_region_mask (image, boxes [box]. box-row, boxes [box]. box_column, bparams->maskwidth, bparams->mask) ; #else if (boxes [box]. boxtype==INGRID)

{ spotnum=getspotnumber (boxes [box]. pin_row, boxes [box]. pin_column, boxes [box]. spot-row, boxes [box]. spot column, p) ; if ((p->spot_type[spot_num]==REG"ULAR) # (p->spot_type [spo tnum] ==POSITIVE)) draw_region_mask (image, boxes [box]. box-row, boxes [box]. box_column, bparams->maskwidth, bparams->mask) ; } #endif else for (box=0 ; box<numboxes ; box++) &num ifdef WETDOT spot_num=get_spot_number (boxes [box].pin_row, boxes [box]. pin_column, boxes [box]. spot_row, boxes [box]. spot column, p) ;

if ((boxes [box].box_type==NOT_IN_GRID) && (p->spot_type [sp ot num] ! =EMPTY)) center_pixel=boxes [box]. boxrow*w+boxes [box]. boxcolumn draw_thick_box (image, center_pixel, outsider, width) ; #else if (boxes [box]. boxtype==INGRID) spot_num=get_spot_number (boxes [box]. pin-row, boxes [box]. pin_column, boxes [box]. spot-row, boxes [box]. spot_column, p) ; if ((p->spot_type [spot_num]==REGULAR) # (p->spot_type [spo tnum] ==POSITIVE)) center_pixel=boxes [box].box_row*w+boxes [box].box_column ; draw_thick_box (image, center_pixel, outsider, width) ;

#endif } } void draw_thick-box (struct image data * image, int center pixel, int outsider, int width) int my, row, my_col, start_row, start col, end-row, end-col, row, col, pixel, w, h ; unsigned short int *data ; data=image->data ; w=image->width ; h=image->height ;

my row = centerpixel/w ; my_col = center_pixel%w; /*top*/ start_row = my_row-outside_r; if (start_row<0) start row=0 ; start-col = mycol-outsider ; if (startcol<0) startcol=0 ; end-row = start_row+width ; if (endrow>=h) endrow = (h-1) ; end-col = my_col+outside-r ; if (end_col>=W) end_col = (w-1) ; for (row=start_row ; row<end_row row++) for (col=start-col ; col<=end_col ; col++) { pixel=row*w+col ; data [pixel] =MAX-INTENSITY/2 ; } /*bottom*/ end-row = my_row+outside_r ; if (end_row>=h) end_row = (h-1) ; start-row = end row-width ;

if (startrow<0) startrow = 0 ; for (row=startrow+l ; row<=endrow ; row++) for (col=start col ; col<=end col ; col++) pixel=row*w+col ; data [pixel] =MAXINTENSITY/2 ; /*left*/ start_row = my row-outside r+width ; if (startrow<0) startrow=0 ; end-row = my_row+outside_r-width ; if (end_row>=H) end_row = (h-1) ; end col = start_col+width ; if (end_col>=w) end_col = (w-1) ; for (row=start_row ; row<=end_row ; row++) for (col=start_col ; col<end_colcol++) pixel=row*w+col ; data [pixel] =MAXINTENSITY/2 ;

/*right*/ end col = my_col+outside_r ; if (end col>=w) end col = (w-1) ; start col = end_col-width ; if (startcol<0) startcol=0 ; for (row=startrow ; row<=endrow ; row++) for (col=startcol+l ; col<=endcol ; col++) pixel=row*w+col ; data [pixel] =MAX_INTENSITY/2 ; void draw_region_mask (struct image data * image, int row, int col, int width, double * mask) int sub-row, sub-col ; int pixel ; int even, odd ;

int mask_point ; unsigned short int * data ; int w, h ; data=image->data ; w=image->width ; h=image->height ; even = (int) ( (double) (width/2)- ( (double) width/2. 0) +1. 1) ; if (even==0) odd=l ; else odd=0 ; maskpQint=0 ; for (subrow=row-width/2 ; (subrow< (row+width/2+odd)) ; sub row++) for (subcol=col-width/2 ; (subcol< (col+width/2+odd)) ; sub col++) { pixel = subrow*w+subcol ;

if ( (sub_row<0) # (sub_col<0) # (sub_row>=h) j) (sub_col>=w) # (pixel>=w*h))<BR> {/* printf ("#bad news in draw region mask row, col, pixel, zip i\n", sub row, sub col, pixel) ; exit (l) ; */ } else if (mask [mask_point]>0. 01) {data [pixel] =MAX_INTENSITY ; mask_point++ ; filters. c #include "defs. h" void filter-list by pixel, attribute (struct overlap * oimage, int ** pixel_positions, int * numpixels, char attributes) {int *old_positions, *new_positions, old_number, new-number, i ;

if (oimage ! =NULL) old_positions=pixel_positions [0] ; old_number=num_pixels[0] ; new number=0 ; for (i=0 ; i<oldnumber ; i++) if (testpixelattributes (oimage->image [old positions [i] ], attributes) ==0) new_number++ ; new_positions= (int *) malloc (newnumber*sizeof (int)) ; if (new_positions==NULL) {printf ("Failed malloc for new positions in filter_list_statistics... \n") ; exit (-l) ; new number=0 ; for (i=0 ; i<oldnumber ; i++) if (test pixel, attributes (oimage->image [old_positions [i] ], attributes) ==0)

{new_positions [new number] =old_positions [i] ; new number++ ; num_pixels [0]=new_number ; free (old-positions) ; pixel_positions [0]=new_positions ; return ; } void set_intensity_by_pixel_attribute (struct overlap * oimage, int * pixel_positions, unsigned short int * pixel intensities, int numpixels, char attributes, unsigned short int intensity) {int i ; if (oimage ! =NULL) for (i=0 ; i<numpixels ; i++) if (test pixel attributes (oimage->image [pixelpositions [ i]], attributes) ! =0)

pixel-intensities [i] =intensity ; find angles. c #include"defs. h" int findanglescomparexbar (const void *c, const void *d) {struct box *a, *b ; a= ( (struct box *) c) ; b= ( (struct box *) d) ; if (a [0]. spotxbar>b [0]. spotxbar) return (0) ; return (l) ; int findanglescompareybar (const void *C, const void *d) {struct box *a, » *b ;

a= ( (struct box *) c) ; b= ( (struct box *) d) ; if (a [0]. spotybar>b [0]. spot_ybar) return (0) ; return (l) ; void find-angles (struct box *b, int n, struct findanglesparams *fa, struct printer *p) {int i, *k na, nb, done, count ; double ax, bx, ay, by, <BR> old pitchx,<BR> old_pitchy, distance2,

dtol2, upper ; /* Get ax and ay */ /* First sort the list by s. spot_xbar into ascending order. */ k= (int *) malloc (sizeof (int) *n) ; if (k==NULL) {printf ("Failed malloc for k in find-angles... \n") ; exit (-l) ; } for (i=0 ; i<n ; i++) k [i] =i ; hsort (b, k, n, sizeof (struct box), findanglescomparexbar) ; _ dtol2=fa [0]. x_vector_tolerance*fa[0].x_vector_tolerance ; upper=p [0]. spotpitch+fa [0]. xvectortolerance ; count=0 ; ax=p [0]. ax ; ay=p [0]. ay ;

do {old_pitchx=ax ; old_pitchy=ay ; ax=0. 0 ; ay=0. 0 ;, na=0 ; for (i=0 ; i< (n-l) ; i++) {done=0 ; for (j=i+l ; (j<n) && (done!=1) && ( (b [k [j]]. spot xbar-b [k [i]]. spot-xbar) <upper) ; j++) { distance2= (b [k [j]]. spot xbar-b [k [i]]. spotxbar-oldpitc hx) * (b [k [j]]. spot_xbar-b [k[i]].spot_xbar-old_pitchx) + (b [k [j]]. spot_ybar-b [k [i]]. spot_ybar-old_pitchy) * (b [k [j]]. spot ybar-b [k [i]]. spot_ybar-old_pitchy) ; if (distance2<dtol2) {done++ ; ax=ax+ (b [k [j]]. spot xbar-b [k [i]]. spot-xbar) ; ay=ay+ (b [k [j]]. spot ybar-b [k [i]]. spot_ybar) ; na++ ; } /* printf ("j-i=%i/n", j-i);

*/ if (na==0) {ax=p [0]. spot_pitch ; ay=0.0 ; else {ax=ax/((double) na) ; ay=ay/ ( (double) na) ; } count++ ; } while ((count<fa[0].iteration_limit) && (fabs (ax-old_pitchx) >fa [0]. convergence_distance)); printf ("Iterations for ax=%i/n", count) ; if (fabs (ax-old_pitchx) >fa [0]. convergence_distance) printf ("Warning, possible nonconvergence in find angles... \n") ; p [0]. ax=ax ; p [0]. ay=ay ; /* Second sort the list by s. spot-ybar into ascending order *. */ hsort (b, k, n, sizeof (struct box), find_agles_c9ompare_ybar) ;

count=0 ; by=p [0]. by ; bx=p [0]. bx ; do {old_pitchy=by ; oldpitchx=bx ; bx=0. 0 ; by=0. 0 ; nb=0 ; dtol2=fa [0]. yvectortolerance*fa [0]. yvectortolerance : upper=p [0]. spot_pitch+fa [0]. y vector tolerance ; for (i=0 ; i< (n-l) ; i++) {done=0 ; for (j=i+l ; (j<n) && (done ! =l) && ((b[k[j]].spot-ybar-b [k [i]]. spot_ybar) <upper) ; j++) distance2= (b [k [j]]. spot_ybar-b [k [i]]. spot_ybar-old_pitc hy) * (b [k [j]]. spot_ybar-b [k [i]]. spot_ybar-old_pitchy) + (b [k [j]]. spotxbar-b [k [i]]. spotxbar-oldpitchx) * (b [k [j]]. spotxbar-b [k [i]]. spotxbar-oldpitchx) ; if (distance2<dtol2)

{done++ ; bx=bx+ (b [k [j]].spot_xbar-b[k[i]].spot_xbar) ; by=by+ (b [k [j]]. spot_ybar-b [k [i]]. spot-ybar) ; nb++ ; if (nb==0) {bx=0. 0 ; by=p [0]. spot_pitch ; } else bx=bx/ ( (double) nb) ; by=by/ ( (double) nb) ; count++ ; } while ((count<fa[0].iteration_limit) && (fabs (by-old_pitchy) >fa [0]. convergence distance)) ; printf ("Iterations for by=%i/n", count) ; if (fabs (by-old_pitchy) >fa [0]. convergence-distance) printf ("Warning, possible nonconvergence in find angles... \n") ; p [0]. bx=bx ; p [ by=by ;

printf ("&num na=*15i ax=%+f ay=%+f nb=%5i bx=%+f by=%+f/n", na, ax, ay, nb, bx, by) ; /* if ( (na ! =0) && (nb ! =0)) p [0]. spot pitch= (na*ax+nb*by)/ (na+nb) ; printf ("#calculated spot pitch=%f/n', p [0]. spot_pitch) ; */ if (p [0]. hexagonal==0) p [0]. dx=p [0]. dy*p [0]. bx/p [0]. by+p [0]. dx ; free (k) ; } void findanglespinbypin (struct image-data *our-image, struct findanglesparams *fa, struct mapspotsparams *m, struct printer *p) {int i, <BR> il<BR> *k, *na, *nb,

done, count, pn, n, sn, num_pins ; double *ax, *bx, *ay, *by, old_pitchx,<BR> old_pitchy, distance2, dtol2, upper ; struct map_image mi ; struct box *b ; b=our-image [0]. boxes ; n=our_image [0].num_boxes ; find angles (b, n, fa, p) ; createmapimage (&mi, m, p) ; map-image remove missing (&mi, p) ; get_internal_width_and_height (&mi) ; printf ("#Coarse/n");

map_coarse (our-image, &mi, p, m [0]. incrementcoarse, m [0]. debug) ; printf ("#Coarse pin-by-pin\n") ; mappinbypin (ourimage, &mi, p, m [0]. increment_coarse_pin_by_pin, m [0]. rangecoarsepinbypinrow, m [0].range_coarse_pin_by_pin_column, m [0]. debug) ; printf ("&num Perform map assignments\n") ; map assign (our-image, &mi, p, m [0]. debug, m [0]. snapnegativestogrid) ; numpins=p [0]. pinsperrow*p [0]. pinspercolumn ; /* Get ax and ay */ ax= (double *) malloc (sizeof (double) *num pins) ; ay= (double *) malloc (sizeof (double) *num_pins) ; na= (int *) malloc (sizeof (int) *num_pins) ; if ((ax==NULL) # (ay==NULL) # (na==NULL)) {printf ("Failed malloc for ax, ay and/or na in find_angles_pin_by_pin...\n"); exit (-l) ;

/* First sort the list by s. spot Ibar into ascending order. */ k= (int *) malloc (sizeof (int) *n) ; if (k==NULL) printf ("Failled malloc for k in find_angles_pin_by_pin... \n") ; exit (-1); } for (i=0 ; i<n ; i++) k [i] =i ; hsort (b, k, n, sizeof (struct box), find_angles_compare_xbar) ; dtol2=fa [0]. x_vector_tolerance*fa [0] .x_vector_olerance ; upper=p [0]. spotpitch+fa [0]. xvectortolerance ; for (pn=0 ; pn<num_pins ; pn++) {count=0 ; ax [pn] =p [0]. ax ; ay [pn] =p [0]. ay ; do {old_pitchx=ax [pn] ; old_pitchy=ay [pn] ;

ax [pn] =0. 0 ; ay [pn] =0. 0 ; na [pn] =0 ; for (i=0 ; i< (n-l) ; i++)- { sn=get_spot_number_from_map_image (&mi, &b [k [i]], mi. rowoffset [pn], mi. col_offset [n]) ; i. f (sn ! = (-1)) if (pn==getpinnumberfromspotnumber (sn, p)) {done=0 ; for (j=i+l ; (j<n) && (done ! =1) && ( (b [k [j]]. spot xbar-b [k [i]]. spot-xbar) <upper) ; j++) distance2= (b [k [j]]. spot xbar-b [k [i]]. spot_xbar-old_pitc hx) * (b [k [j]]. spot xbar-b [k [i]]. spotxbar-oldpitchx) + (b [k [j]]. spotybar-b [k [i]]. spot_ybar-old_pitchy) * (b [k [j]]. spot ybar-b [k [i]]. spot_ybar-old_pitchy) ; if (distance2<dtol2) {done++ ; ax [pn] =ax [pn] + (b [k [j]]. spot xbar-b [k [i]]. spot-xbar) ; ay [pn] = ay [pn] + (b [k [j]]. spot ybar-b [k [i]]. spot-ybar) ; na [pn] ++ ;

if (na [pn] ==0) {ax [pn] =p [0]. ax ; ay [pn] =p [0]. ay ; else {ax [pn] =ax [pn] / ((double) na [pn]) ; ay [pn] = ay [pn] / ((double) na [pn]) ; } count++ ; while ((count<fa [0] .iteration_limit) && (fabs (ax [pn] -old_pitchx) >fa [0]. convergence_distance)) ; if (fabs (ax [pn]-old_pitchx) >fa [0]. convergence_distance) {ax [pn] =p [0]. ax ; ay [pn] =p [0]. ay ; printf ("Warning, possible nonconvergence in find angles... \n") ; printf ("Spot pitch for pin ii set to spot pitch specified in printer file... \n", pn) ; p [0]. ax=ax [0] ;

p [0]. ay=ay [0] ; /* Gey bx and by */ bx= (double *) malloc (sizeof (double) *numpins) ; by= (double *) malloc (sizeof (double) *numpins) ; nb= (int *) malloc (sizeof (int) *num_pins) ; if ((bx==NULL) # (by==NULL) # (nb==NULL)) {printf ("Failed malloc for bx, by, and/or nb in findanglespinbypin... \n") ; exit (-l) ; /* Second sort the list by s. spot_ybar into ascending order *. */ hsort (b, k, n, sizeof (struct box), find angles compare ybar) ; dtol2=fa [01. y_vector_tolerance*fa [0] .y_vector_olerance ; upper=p [0]. spot_pitch+fa [0]. y vector-tolerance ; for (pn=0 ; pn<num_pins ; pn++) {count=0 ; by [pn] =p [0]. by ; bx [pn] =p [0]. bx ; do

{old_pitchy=by [pn] ; oldjpitchx=bx [pn] ; bx [pn] =0. 0 ; by [pn] =0. 0 ; nb [pn] =0 ; for (i=0 ; i< (n-l) ; i++) { sn=get_spot_number_from_map_image (&mi, &b [k [i]], mi. row-offset [pn], mi. coloffset [pn]) ; if (sn ! = (-l)) if (pn==get_pin_number_from_spot_number (sn, p)) {done=0 ; for (j=i+l ; (j<n) && (done !=1) && ( (b [k [j]]. spot_ybar-b [k [i]]. spot-ybar) <upper) ; j++) distance2= (b [k [j]]. spot-ybar-b [k [i]]. spot_ybar-old_pitc hy) * (b [k [j]]. spot_ybar-b [k [i]]. spot_ybar-old_pitchy) + (b [k [j]]. spot xbar-b [k [i]]. spotxbar-oldpitchx) * (b [k [j]]. spot xbar-b [k [i]]. spot_xbar-old_pitchx) ; if (distance2<dtol2) {done++ ; bx [pn] =bx [pn] + (b [k [j]] .spot_xbar-b [k [i]]. spot-xbar) ;

by [pn] =by [pn] + (b [k [j]]. spot ybar-b [k [i]]. spot_ybar) ; nb [pn] ++ ; if (nb [pn] ==0) { bx [pn] = p[0]. bx ; by [pn] =p [0]. by ; else { bx [pn] = bx [pn] / ((double) nb [pn]) ; by [pn] =by [pn] / ((double) nb [pn]) ; count++ ; while ((count<fa [0] .iteration_limit) && (fabs (by [pn]-old_pitchy) >fa [0]. convergence_distance)) ; if (fabs (by [pn]-old_pitchy) >fa [0]. convergence_distance) {bx [pn] =p [0]. bx ; by [pn] = p [0]. by ; printf ("Warning, possible nonconvergence in find_angles... \n") ; printf ("Spot pitch for pin %i set to spot pitch specified in printer file... \n", pn) ;

} p [0]. bx=bx [0] ; p [0]. by=by [0] ; for (pn=0 ; pn<num_pins ; pn++) printf ("pn=%31 na=%5i ax=%+f ay=%+f nb=%5i bx=%+f by=%+f\n", pn, na [pn], ax [pn], ay [pn], nb [pn], bx [pn], by [pn]) ; free_map_image (&mi) ; p [0]. axp=ax ; p [0]. ayp=ay ; p [0]. bxp=bx ; p [0]. byp=by ; free (na) ; free (nb) ; free (k) ; find-array. c &num include defs. h" void find-array (struct image data * image, struct parameters * allparams)

parameter check (image, all_params) ; image->integrated data=integrate_regions (image, &all_params->integration) ; image->integrated data-small=integrate_regions (image, &allparams->integrationsmall) ; if ( (all_params->output_image. integrated_flag==1) && (image->integrated_data!=NULL) && (image->integrateddatasmall ! =NULL)) output-integrated-image (image, &all_params->output_image) ; printf ("#Finding boxes/candidate spots... \n") ; if (allparams->findboxes. fastflag==l) findboxesfast (image, allparams) ; printf ("found %i boxes in find_boxes_fast\n", image->numboxes) ; } else find_boxes (image, all_params) ; printf ("found %i boxes in find_boxes\n", image->numboxes) ;

crop image data (image, &allparams->cropimagedata. spotparams) ; if (all_params->find_angles.do_find_angles==1) { if (all_params->printer_info.sub_grid_vectorization==0) find angles (image->boxes, image->numboxes, &allparams->findangles, &allparams->printerinfo) ; else findanglespinbypin (image, &allparams->findangles, &all_params->map_spots, &all_params->printer_info) ; map-spots (image, &all_params->map_spots, &all_params->printer_info) ; printf ("#Transfer spots to grid... \n") ; transfer_spots_to_grid (image, &allparams->printerinfo) ; printf ("&num Fill in empty spots... \n") ; fill_in_empty_boxes (image, &allparams->printerinfo, &all_params->integration, &all_params->integration,_small,

&allparams->background, &all_params->crop_image_data.spot_params) ; printf ("#End find_array... \n") ; void find_array_multi (struct image data * sum, struct image data * images [], int numimages, struct parameters * all_params) parameter-check (sum, all_params) ; sum->integrateddata=integrateregions (sum, &all_params->integration) ; sum->integrateddatasmall=integrateregions (sum, &all_params->integration_small) ; if ((all_params->output_image. integrated_flag==l) && (sum->integrated_data!=NULL) && (sum->integrateddatasmall ! =NULL)) { outputintegratedimage (sum, &all_params->output_image) ; } if (all_params->find_boxes.fast_flag==1) { find-boxes-fast (sum, all_params) ;

printf ("found *-. boxes in find_boxes_fast\n", sum->numboxes) ; else { find boxes (sum, all_params) ; printf ("found %i boxes in find_boxes\n", sum->numboxes) ; crop_image_data (sum, &all_params->crop_image_data.spot_params) ; if (all_params->find_angles.do_find_angles==1) { if (all_params->printer_info.sub_grid_vectorization==0) findangles (sum->boxes, sum->numboxes, &allparams->findangles, &allparams->printerinfo) ; else find angles-pin by pin (sum, <BR> <BR> <BR> &allparams->findangles,<BR> <BR> <BR> <BR> &allparams->mapspots, &all_params->printer_info) ;

map spots (sum, &all_params->map_spots, &allparams->printerinfo) ; transfer-spots to grid (sum, &alljparams->printerinfo) ; fill in empty boxes (sum, &allparams->printerinfo, &all_params->integration, &all_params->integraton_small, &all_params->background &all_params->crop_image_data. spot_params) ; multiimagecreateboxes (sum, images, num_images, &al-params->integration_out, &al-params->integration_small, &allparams->background) ; if (allparams->cropimagedata. shiftflag==0) { multi_image_crop_image_data (sum, images, numimages, &allparams->cropimagedata. spotparams) ; } else

{ multi_image_crop_image_data_shift (sum, images, numimages, &all_params->crop_image_data) ; find boxes. c #include"defs. h" void find_boxes_fast (struct image_data *our_image, struct parameters *our_params) {int n, <BR> <BR> <BR> i,<BR> <BR> <BR> <BR> w, h, <BR> <BR> <BR> <BR> numboxes=0,<BR> <BR> <BR> <BR> <BR> numpossibleboxes,<BR> <BR> <BR> <BR> estimatednumboxes, limit_fur, limitcen, row, col, <BR> <BR> <BR> <BR> r-int,<BR> <BR> <BR> <BR> r int small, step,

pixel, count, count unclaimed=0, count total=0, rintsave, *box_list ; Integrated *id, *ids ; double distance, fractionbyfurcation ; struct box test-box ; unsigned short int *d ; struct printer * p ; w=ourimage [0]. width ; h=ourimage [0]. height ; d=our-image [0]. data ; id=ourimage [0]. integrateddata ; ids=ourimage [0]. integrated-data-small ; rint=ourparams [0]. integration. integration_radius ; r_int_small=our_params [0] .integration_small. integration radius ; limitfur=ourparams [0]. findboxes. limitfurcation ; limit_cen=our_params [0] .find_boxes.limit_center ;

fraction_by_furcation=our_params [0]. find_boxes. fraction by furcation ; p=&our_params [0]. printer info ; printf ("furcation type = %i\n". our_params [0]. find_boxes.spot_params.furcation_type) ; n=w*h ; <BR> <BR> numpossibleboxes=ourparams [0]. printerinfo. pinsper column* our_params [0]. printerinfo. pinsperrow* ourparams [0]. printerinfo. spotsperrow* our_params [0]. printer-info. spots-per column ; r_int_save=our_params->integration. integration_radius ; ourparams->integration. integrationradius= (int) (our_pa rams->printer_info. spot_diameter/2. 0) ; step = (int) (p->spot_pitch/2. 0+0. 5) ; printf ("step = %i\n", step) ; ourparams->findboxes. spotparams. cropwidth=

(int) ( sqrt (2. 0) * ( (double) step)/2. 0+ourparams->printerinfo. s pot_diameter/2. 0+0. 5) + (int) (0. 2*ourparams->printerinfo. spot_diameter/2.0+0 . 5) ; <BR> <BR> ourparams->findboxes. spotparams. cropheight=ourpara ms->findboxes. spotparams. cropwidth ; estimatednumboxes= (int) ( ( (double) (w*h))/ ( (double) (step*step) +0. 5)) +1 ; printf ("width = %i\n", our params->find boxes. spot_params. crop width) ; box_list= (int *) malloc (estimated_num_boxes*sizeof (int)) ; if ( (boxlist==NULL)) printf ("Failed to allocate box-list in find_boxes... \n") ; exit (-l) ; test_box. box. area= (int) ((2*r_int-1) * (2*r int-1)) ; test_box.small_box,. area= (int) ((2*r_int_small-1) * (2*r_in t_small-1)) ;

/*area= (p->spotdiameter*p->spotdiameter) ; */ printf ("spot must be within f of row, col\n", (sqrt (2. 0) * ( (double) step)/2. 0)) ; for (row=step ; row<h ; row+=step) { for (col=step ; col<w ; col+=step) count_total++ ; pixel=row*w+col ; if (id [pixel] >0. 0) { count-unclaimed++ ; testbox. boxrow=row ; test box. box column=col ; test_box. box. average=id [pixel] ; test_box. small_box.average=id_s [ixel] ; getlargestspotaverageposition (ourimage, &testbox, &ourparams [0]. findboxes. spotparams) ; pixel= ((int) (test_box.spot_ybar+0. 5)) *w+ (int) (test-box. spot_xbar+0. 5) ; distance=sqrt ((((double) test_box.box_row) - test_box.spot_ybar) *

(((double) test_box.box_row) - test box. spot ybar) + (((double) test_box.box_column) - test_box.spot_xbar) * ( ( (double) test box. box column)- test box. spot xbar)) ; if ((id[pixel] > 0. 0) && (test_box.spot_rmax !=0.0) && (distance< (sqrt (2. 0) * ( (double) step)/2. 0) +0. 5) && (testbox. spotrbar> (0. 2*p [0]. spot_diameter)) && (testbox. spotrbar< (0. 8*p [0]. spot_diameter)) && (test_box.spot_rmax/(test_box.spot_rmin+0. 0000001) <100.

0) ) /*printf (" good") ; */ /*center*/ count=0 ; while ((count<limit_cen) && (distance>ourparams [0]. findboxes. centertolerance)) count++ ; test_box.box_row = (int) (test box. spot ybar+0. 5) ;

test box. box column= (int) (test box. spot xbar+0. 5) ; test_box. box. average=id [pixel] ; test_box. small_box.average=id_s [pixel] ; if (test_box. box. average<0. 0) test_box. box. average=-testbox. box. average ; <BR> <BR> getlargestspotaverageposition (ourimage, &testbox, &ourparams [0]. findboxes. spotparams) ; distance=sqrt ( ( ( (double) testbox. boxrow)-testbox. spotybar) * (((double) test_box.box_row) - test_box.spot_ybar) + (((double) test_box.box_column) -test box. spot xbar) * (((double) test_box.box_column) -test box. spot, xbar)) ; pixel= ((int) (test_box.spot_ybar+0. 5)) *w+ (int) (test_box. spot xbar+0. 5) ; } /*printf (" %i center steps", count) ; */ if (id [pixel] >0. 0)

claim_intensity (our_image, &our_params->integration, pixel) ; box_list [num_boxes] = ((int) (test_box. spot_ybar+0. 5)) *w + (int) (test_box.spot_xbar+0. 5) ; nbboxes++ ; else /*printf ("... didn't center...") ; */ /*printf ("\n") ; */ ourparams->integration. integrationradius=rintsave ; printf ("found %i boxes, unclaimed = 0-. total = %i\n", numboxes, countunclaimed, counttotal) ; free (ourimage [0]. integrateddata) ; ourimage [0]. integrateddata=NULL ; free (our_image [0]. integrated_data_small) ; our-image [0]. integrated data-small=NULL ; ourimage [0]. numboxes=numboxes ;

our_image [0]. boxes= (struct box *) malloc (numboxes*sizeof (struct box)) ; if (our_image [0] .boxes==NULL) {printf ("Failed malloc for box structures in find_boxes... \n") ; exit (-l) ; for (i=0 ; i<num boxes ; i++) create_box (our_image, box_list [i]/w, boxlist [i] %w, &our_params [0]. integration, &our_params [0].integration_small, &our_params [0]. background, &our_image [0]. boxes [i]) ; free (box_list) ; void find boxes (struct image_data *our_image, struct parameters *our_params) {int n, i, w, h, num boxes=0, num centeredboxes=0,

fur_boxes=0, <BR> <BR> <BR> numpossibleboxes,<BR> <BR> <BR> estimatednumboxes, inspect, inspect new, count, limit_fur, limit_cen, row, col, r-int, r_int_small, *sd, *box_list, *centered_box_list, center_loops, limit-center loops=2 ; Integrated *id, *ids ; double distance, fraction_by_furcation ; struct box test-box ; unsigned short int *d ; w=ourimage [0]. width ;

h=ourimage [0]. height ; d=our-image [0]. data ; id=our-image [0]. integrated_data ; ids=ourimage [0]. integrateddatasmall ; r_int=our_params[0]. integration. integration_radius ; rintsmall=ourparams [0]. integrationsmall. integration radius ; limitfur=ourparams [0]. find_boxes.limit_furcation ; limit_cen=our_params[0].find_boxes.limit_center ; fractionbyfurcation=ourparams [0]. findboxes. fraction by furcation ; n=w*h ; estimated_num_boxes=w*h/r_int/r_int/4+1 ; <BR> <BR> numpossibleboxes=ourparams [0]. printerinfo. spottype s. number [REGULAR] + ourparams [0]. printerinfo. spottypes. number [POSITIVE] ; sd= (int *) malloc (sizeof (int) *n) ; if (sd==NULL) {printf ("Failed to allocate memory for sorting (pointer) in find_boxes... \n") ;

exit (-l) ; create-box (our-image, h/2, w/2, &our_params[0]. integration, &ourparams [0]. integrationsmall, &our_params[0]. background, &testbox) ; for (i=0 ; i<n ; i++) id [i] = id_s[i]-id[i] ; sd [i] =i ; qsort_integrated (id, sd, n) ; for (i=0 ; i<n ; i++) id [i]=id_s[i]-id [i] ; box_list (int *) malloc (estimatednumboxes*sizeof (int)) ; centered_box_list= (int *) malloc (estimatednumboxes*sizeof (int)) ; if ((box_list==NULL) && (centeredboxlist==NULL)) {printf ("Failed to allocate box-list or centerecd_box_list in find_boxes... \n") ; exit (-l) ;

/* insert code for furcation during box integration here if desired. */ for (i=o ; (i<n) && (fur_boxes< (fraction_by_furcation*num_possible_boxes)); i++) if (id [sd [i]] >0. 0) {inspect=inspectbox (ourimage, ourparams, sd [i]/w, sd[i]%w) ; if (inspect== (-l)) {claimintensity (ourimage, &ourparams [0]. integration, sd [i]) ; centered_box_list [fur_boxes] = sd [i] ; fur_boxes++ ; printf (" \rfur_boxes=%i box=%i\r", fur_boxes, sd[i]) ; fflush (stdout) ; if ((inspect> (-1)) && (id[inspect] > 0. 0)) {count=0 ; while ((inspect > (-1)) && (id [inspect] >0. 0) && (count<limitfur)) {inspectnew=inspectbox (ourimage, our_params, sd[inspect]/w, sd[inspect]%w) ; if (inspect new== (-l)) claim-intensity (our-image, &ourparams [0]. integration, inspect) ; centered_box_list [fur_boxes]=inspect ;

fur_boxess++ ; inspect=inspectnew ; count++ ; /* end code for furcation during box integration */ numboxes=furboxes ; numcenteredboxes=furboxes ; for (i=0 ; i<numcenteredboxes ; i++) box_list[i]=centered_box_list [i] ; /* claim all boxes including those that are not centered */ for (i=0 ; (i<n) && (numboxes<numpossibleboxes) ; i++) if (id [sd [i]] >0. 0) {claim intensity (our-image, &our_params[0].integration, sd[i]); boxlist [numboxes] =sd [i] ; nbboxes++ ;

/* This line is simply here to calculate two areas */ /* create box (our image, h/2, w/2, &our_params [0]. integration, &our_params [0]. integration-small, &our_params[0]. background, &testbox) ; */ center-loops=0 ; do for (i=0 ; i<n ; i++) if (id [sd [i]] <0. 0) id [sd [i]] =-id [sd [i]] ; /* Need to claim already centered boxes */ for (i=0 ; i<numcenteredboxes ; i++) claim-intensity (our-image, &our_params[0]. integration, centeredboxlist [i]) ; /* Try to center boxes that aren't already known to be centered */ for (i=numcenteredboxes ; i<numboxes ; i++) {/* testbox. box row=box list [i]/w ; test_box.box_column=box_list [i]%w ;

create_box (our_image, test_box.box-row, testbox. boxcolumn, &ourparams [0]. integration, &ourparams [0]. integrationsmall, &our_params [0]. background, &testbox) ; <BR> <BR> <BR> */<BR> <BR> <BR> testbox. boxrow=boxlist [i]/w ; testbox. boxcolumn=boxlist [i] %w ; test_box. box. average=id [boxlist [i]] ; test-box. smallbox. average=ids [boxlist [i]] ; if (test_box. box. average<0. 0) test_bx. box. average=-testbox. box. average ; getlargestspotstatistics (ourimage, &testbox, &ourparams [0]. findboxes. spotparams) ; count=0 ; do {count++ ; /* row = (int) (test_box. spots [testbox. bestspot]. ybar+0. 5) ; col = (int) (test_box. spots [test_box.best_spot]. xbar+0. 5) ; create-box (our-image, row, col, &ourparams [0]. integration, &ourparams [0]. integrationsmall, &our_params[0].background, &test_box) ;

*/ test_box.box_row = (int) (test box. spot ybar+0. 5) ; test_box.box_column= (int) (testbox. spotxbar+0. 5) ; test_box. box. average=id [test box. boxrow*w+testbox. box column] ; testbox. smallbox. average=ids [testbox. boxrow*w +testbox. boxcolumn] ; if (test_box. box. average<0. 0) test_box. box. average=-testbox. box. average ; getlargestspotstatistics (ourimage, &testbox, &ourparams [0]. findboxes. spotparams) ; distance=sqrt ((((double) test_box.box_row) - test_box.spot_ybar) * (((double) test_box.box_row) - test_box.spot_ybar) + (((double) test_box.box_column) - test_box.spot_xbar) * (((double) test_box.box_column) - test box. spot xbar)) ; } while ((count<limit_cen) && (distance>ourparams [0]. find boxes. center tolerance)) ; row = (int) (test_box.spot_ybar+0. 5) ;

col = (int) (test-box. spot xbar+0. 5) ; if ((test_box.spot_rmax! = 0.0) && (testbox. spotrbar> (0. 2*our_params [0]. printer_info. spo tdiameter),) && (testbox. spotrmax< (0. 5*our_params [0]. printer-info. spo t_pitch)) && (distance<our_params [0]. find-boxes. center-tolerance) (id [row*w+col] >0. 0)) claim-intensity (our-image, &our_params[0]. integration, row*w+col) ; centered_box_list [num_centered_boxes] = row*w+col; num centered boxes++ ; /* Transfer centered boxes to box list */ for (i=0 ; i<numcenteredboxes ; i++) box_list[i]=centered_box_list [i] ; numboxes=numcenteredboxes ; /* Claim centered boxes */

for (i=0 ; (i<n) && (numboxes<numpossibleboxes) ; i++) if (id[sd[i]] >0.0) {claimintensity (ourimage, &our_paramsfo]. integration, sd [i]) ; boxlist [numboxes] =sd [i] ; nbboxes++ ; } center-loops++ ; while (center_loops<limit_center_loops) ; free (sd) ; free (our-image [0]. integrated_data) ; out-image [0]. integrateddata=NULL ; our-image [0]. boxes= (struct box *) malloc (numboxes*sizeof (struct box)) ; if (our_image[0]. boxes==NULL) {printf ("Failed malloc for box structures in find_boxes... \n") ; exit (-l) ; for (i=0 ; i<num boxes ; i++) create_box (our_image, box_list[i]/w, box_list [i] %w,

&our_params[0]. integration, &our_params [0]. integration-small, &our_params [0]. background, &our_image[0].boxes[i]) ; ourimage->numboxes=numboxes ; free (box_list) ; free (centered_box_list) ; return ; } void claim-intensity (struct image_data *our_image, struct integration params *iparams, int box) int row, col, start_row, start_col, my_row, my_col, w, h, r-int, il

d, r2 ; w=ourimage [0]. width ; h=our_image [0]. height ; r_int=iparams [0]. integration_radius ; my_row = box/w ; my_col = box-. ; start-row = my_row-2* (r_int-1) ; if (startrow<0) start row=0 ; start-col = mycol-2* (rint-l) ; if (startcol<0) start col=0 ; r2=4* (rint-l) * (r_int-1) ; for (row=startrow ; (row<= ((my_row+2*(r_int-1))) && (row<h)) ; row++) for (col=start-col ; (col<= ((my_col+2*(r_int-1))) && (col<w)) ; col++) {j=row*w+col ; d= (row-my_row) * (row-my_row) + (col-my-col) * (col-my_col) ; /*printf ("%f %f\n", r2, d) ; */

if ((our_image[0].integrated_data[j] >0. 0) && (d<=r2)) our_image[0].integrated_data[j] = -our_image[0]. integrate d data [j] ; void crop region (int row, int col, int w, int h, unsigned short int * d, int * crop w, int * crop, unsigned short int ** cropd, int * rs, int * cs, int * re, int * ce, struct spotfindingparams * sp) { int r, c, k, j ; if ((row-sp[0].crop_height) < 0) {rs [0] =0 ; crop_h [0] =row ;

else {rs [0]=row-sp[0].crop_height ; crop_h[0]=sp[0].crop_height ; } if ((row+sp[0].crop_height) > (h-1)) {re [0]=h-1 ; croph [0] =croph [0] +h-l-row ; else {re [0]=row+sp[0].crop_height ; croph [0] =croph [0] +sp [0]. cropheight ; crop_h [0] ++ ; if ((col-sp[0].crop_width) < 0) {cs [0] = 0 ; cropw [0] =col ; else {cs [0] =col-sp [0]. cropwidth ; crop_w[0]=sp[0].crop_width ; if ((col+sp[0].crop_width) > (w-1)) {ce [0]=w-1 ; cropw [0] =cropw [0] +w-l-col ;

} else {ce [0] =col+sp [0]. crop-width ; crop_w[0]=crop_w[0]+sp[0].crop_width ; } crop_w[0] ++ ; crop_d [0] = (unsigned short int *) malloc (sizeof (unsigned short int) *cropw [0] *croph [0]) ; if (crop_d==NULL) {printf ("Failed malloc for crop_d [0] in crop region... \n") ; exit (-l) ; /* Lets crop the data */ ; k=0 ; for (r=rs [0] ; r< (re [0]+1) ; r++) {j=r*w ; for (c=cs [0] ; c< (ce [0]+1) ; c++) {cropd [0] [k]-d [j+c] ; k++ ;

void print_box_info (struct box * b) {printf ("boxrow=%i\n", b [0]. boxrow) ; printf ("box_column=%i\n", b [0]. box_column) ; printf ("box_type=%i\n", b[0].box_type) ; printf ("box_average=%f\n", b [0]. box. average) ; void get_largest_spot_statistics (struct image data *image, struct box * b, struct spot_finding_params *params) {int w, h, r, c, i il k, crop w, crop, rs, re, cs, ce, *crops,

*area, <BR> *row max,<BR> *row min,<BR> *col max, *col min, p-flag ; unsigned short int *d, *crop_d, *realist ; double xbar, ybar, distance, distance sum ; w=image [0]. width ; h=image [0]. height ; d=image [0]. data ; crop region (b [0]. box-row, b [0]. box column, w, h, d, &cropw, &croph, &cropd, &rs, &cs, &re, &ce, params) ; b [0]. threshold=set_threshold ((double) b [0]. box. average, (double) b [0]. small_box. average, (double) b [0]. box. area, (double) b [0]. small_box. area,

(double) params [0]. estimated spot area, (double) params [0]. fraction_Ibar) ; b [0]. num_spots=find_spots (crop-w, crop_h, crop_d, &crop_s, (int) b [0]. threshold, ( (int) MAX_INTENSITY), params [0]. furcation-type) ; if (b [0]. num_spots! = 0) {area= (int *) malloc (sizeof (int) *b [0]. numspots) ; row_max= (int *) malloc (sizeof (int) *b [0]. numspots) ; row min= (int *) malloc (sizeof (int) *b [0]. num_spots) ; col max= (int *) malloc (sizeof (int) *b [0]. numspots) ; col_min= (int *) malloc (sizeof (int) *b [0]. numspots) ; if ((area==NULL) <BR> <BR> <BR> <BR> <BR> (row_max==NULL) ##<BR> <BR> <BR> <BR> <BR> <BR> <BR> (row_min==NULL) ##<BR> <BR> <BR> <BR> <BR> <BR> <BR> (col_max==NULL) ##<BR> <BR> <BR> <BR> <BR> <BR> <BR> (colmin==NULL)) {printf ("Failed malloc for'area'in getlargestspotstatistics... \n") ; exit (-l) ; for (j=0 ; j<b [0]. numspots ; j++) row_max[j] = 0 ; rowmin [j] =croph-l ;

colmax [j] =0 ; colmin [j] =cropw-l ; area [j] =0 ; for (r=0 ; r<croph ; r++) j=r*crop_w ; for (c=0 ; c<cropw ; c++) i=crop_s [j+c] ; if (i>-l) {area [i]++ ; if (r>rowmax [i]) row_max[i]=r ; if (r<rowmin [i]) row_min[i]=r ; if (c>col_max[i]) col_max[i]=c ; if (c<col_min[i]) col_min[i]=c ; } k=0 ; for (j=0 ; j<b [0]. num-spots ; j++) if (area [j] >area [k]) k=j ;

b [0]. spot_height=row_max[k] - row_min[k}+1 ; b [0]. spot_width = col_max[k]-col_min[k]+1 ; area-list= (unsigned short int *) malloc (area [k] *sizeof (unsigned short int)) ; if (arealist==NULL) {printf ("Failed malloc for area list in get_largest_spot-statistics... \n") ; exit (-l) ; /* Calculate spot morphology information based upon the spot selected above. */ i=0 ; xbar=0. 0 ; ybar=0. 0 ; for (r=rowmin [k] ; r< (row_max[k]+1) ; r++) j=r*crop_w ; for (c=col_min [k] ; c< (col_max[k]+1) ; c++) if (crop_s [j+c] ==k) {xbar=xbar+((double) c) ; ybar=ybar+ ((double) r) ; area-list [i] =crop_d [j+c] ; i++ ; else

crops [j+c] =-l ; get_list_statistics (area-list, area [k], &b [0]. spot), ; free (area-list) ; xbar=xbar/b [0]. spot. area ; ybar=ybar/b [0]. spot. area ; b [0]. spotxbar=xbar + ( (double) cs) ; b [0]. spot_ybar=ybar + ( (double) rs) ; b->distance_from_spot_to_box=sqrt ((((double) b->boxrow)-ybar) * (((double) b->box_row)-ybar) + ( ( (double) b->boxcolumn)-xbar) * ( ( (double) b->boxcolumn)-xbar)) ; b [0]. spot rmax=0. 0 ; b [0]. spot_rmin=((double) crop_w) * ( (double) crop) ; b [0]. spot-perimeter=0 ; distance_sum=0. 0 ; for (r=rowmin [k] ; r< (row_max[k]+1) ; r++) {j=r*crop_w ; for (c=col_min[k] ; c < (col_max[k]+1) ; c++) if (crops [j+c] ==k) {flag=0 ;

/*Look right */ if (c== (crop w-1)) p_flag=1 ; else if (crops [j+c+1] !=k) p_flag=1 ; /*Look left*/ if (c==0) p_flag=1 ; else if (crop-s [j+c-1] ! =k) p_flag=1 ; /*Look up*/ if (r==0) p_flag=1 ; else if (crops [j+c-crop_w] !=k) p_flag=1 ; /*Look down*/ if (r== (crop h-1)) p_flag=1; else if (crop_s[j+c+crop_w] !=k) p_flag=1 ; if (p_flag==l)

{distance=sgrt ((((double) c)-xbar) * ( ( (double) c)-xbar) + ( ( (double) r)-ybar) * ( ( (double) r) -ybar)) ; distancesum=distancesum+distance ; b [0]. spot-perimeter++ ; if (distance>b [0]. spot_rmax) b [0]. spot-rmax=distance ; if (distance<b [0]. spot_rmin) b [0]. spotrmin=distance ; if (b [0]. spot_perimeter!=0) b [0]. spot_rbar=distance_sum/((double) b [0]. spot_perimeter) ; else b [0]. spotrbar=0. 0 ; free (area) ; free (row max) ; free (row min) ; free (col_max) ; free (col min) ; else b [0]. spot xbar= ((double) b [0]. box-column) ; b [0]. spot-ybar= ( (double) b [0]. box-row) ; b [0]. spot_rbar=0. 0 ;

b [0]. spot_rmin=0. 0 ; b [0]. spot_rmax=0. 0 ; b [0]. spot_perimeter=0 ; b [0]. spot width=0 ; b [0]. spotheight=0 ; get_list_statistics (NULL, 0, &b [0]. spot) ; b->distancefromspottobox=DBLMAX ; free (crop_d); free (crop_s) ; return ; void cropimagedata (struct image data *our-image, struct spot_finding_params *sparams) {int i ; for (i=0 ; i<our-image [0]. numboxes ; i++) get_largest_spot_statistics (our-image, &our_image [0]. boxes [i], sparams) ; return ;

int inspect box (struct image data *our-image, struct parameters *our_params, int row, int col) {struct box b ; create-box (our-image, row, col, &our_params [0]. integration, &our_params [0]. integration_small, &our_params [0]. background, &b) ; getlargestspotstatistics (our-image, &b, &ourparams [0]. findboxes. spotparams) ; if ((b. spot_rbar> (0. 2*ourparams [0]. printerinfo. spotdi ameter)) && (b. spot_ramax< (0. 5*our_params [0]. printer-info. spot pitch ))) if (sqrt ((b. spot_xbar- ((double) b. box_column)) * (b. spot xbar- ( (double) b. box_column)) + (b. spot_ybar- ((double) b. box row)) * (b. spot_ybar- ((double) b. box_row))) <3. 0) return (-l) ; else return ( ( (int) b. spot_ybar) *our_image [0]. width + ( (int) b. spot xbar)) ;

return (-2) ; void get_largest_spot_perimeter (int *perimeter_pixels, struct image data *image, struct box * b, struct spot_finding_params *params) {int w, h, r, c, i, il k, crop, crop, rs, re, cs, ce, <BR> <BR> <BR> <BR> <BR> d col,<BR> <BR> <BR> <BR> <BR> <BR> <BR> d-row, *crops, *area, *row max,

*row min,<BR> *col max, *colin, p_flag ; unsigned short int *d, *crop_d, *realist ; double xbar, ybar, distance, distance_sum ; w=image [0]. width ; h=image [0]. height ; d=image [0]. data ; crop region (b [0]. box-row, b [0]. box_column, w, h, d, &cropw, &croph, &cropd, &rs, &cs, &re, &ce, params) ; b [0]. threshold=setthreshold ( (double) b [0]. box. average, (double) b [0]. small_box. average, (double) b [0]. box. area, (double) b [0]. small_box. area, (double) params [0]. estimatedspotarea, (double) params [0]. fraction_Ibar) ;

b num numspots=findspots (cropw, croph, cropd, &crop_s, (int) b [0]. threshold, ( (int) MAX-INTENSITY), params [0]. furcation-type) ; if (b [0]. num_spots ! =0) {area= (int *) malloc (sizeof (int) *b [0]. numspots) ; row_max= (int *) malloc (sizeof (int) *b [0]. numspots) ; row min= (int *) malloc (sizeof (int) *b [0]. numspots) ; col max= (int *) malloc (sizeof (int) *b [0]. numspots) ; col_min= (int *) malloc (sizeof (int) *b [0]. numspots) ; if ((area==NULL) (row_max==NULL) (row_min==NULL) (colmax==NULL) jj<BR> (colmin==NULL)) {printf ("Failed malloc for'area'in get_largest_spot_perimeter.../n") ; exit (-l) ; for (j=0 ; j<b [0]. num_spots ; j++) {rowmax [j] =0 ; rowmin [j] =croph-l ; colmax [j] =0 ; col_min [j] =crop_w-1 ; area [j] =0 ;

for (r=0 ; r<croph ; r++) j=r*crop_w ; for (c=0 ; c<cropw ; c++) i=crop_s [j+c] ; if (i>-l) {area [il ++ ; if (r>rowmax [i]) row_max [i] =r ; if (r<rowmin [i]) row_min [i] =r ; if (c>col_max [i]) col_max [i] =c ; if (c<col_min [i]) col_min [i] =c ; } k=0 ; for (j=0 ; j<b [0]. numspots ; j++) if (area [j] >area [k]) k=j ; b [0]. spot_height=row_max [k] -row_min [k] + 1 ; b [0]. spot_width =col_max [k] - col_min [k] + 1 ; area-list= (unsigned short int *) malloc (area [k] *sizeof (unsigned short int)) ;

if (arealist==NULL) {printf ("Failed malloc for area-list in getlargestspotperimeter... \n") ; exit (-l) ; /* Calculate spot morphology information based upon the spot selected above. */ i=0 ; xbar=0. 0 ; ybar=0. 0 ; for (r=rowmin [k] ; r< (row_max [k] + 1) ; r++) j=r*crop_w ; for (c=col min [k] ; c< (col_max [k] + 1) ; c++) if (crops [j+c] ==k) {xbar=xbar+ ((double) c) ; ybar=ybar+ ( (double) r) ; area-list [i] =crop_d [j+c] ; i++ ; else crops [j+c] =-l ; } get_list_statistics (area_list, area [k], &b [0]. spot) ; free (area-list) ;

xbar=xbar/b [0]. spot. area ; ybar=ybar/b [0]. spot. area ; b [0]. spotxbar=xbar + ((double) cs) ; b [0]. spot_ybar=ybar + ( (double) rs) ; b [0]. spot rmax=0. 0 ; b [0]. spot_rmin= ((double) crop_w) * ( (double) crop_h) ; b [0]. spot perimeter=0 ; distance_sum=0. 0 ; for (r=rowmin [k] ; r< (row_max [k] +1) ; r++) j=r*crop_w ; for (c=colmin [k] ; c< (col_max [k] +1) ; c++) if (crops [j+c] ==k) {flag=0 ; /*Look right */ if (c== (crop w-1)) p_flag=l ; else if (crop_s {j+c+1] ! =k) p_flag=l ; /*Look left*/ if (c==0) p_flag=1 ; else

if (crop-s [j+c-l] ! =k) p_flag=1 ; /*Look up*/ if (r==0) p_flag=1 ; else if (crop_s[j+c-crop_w] !=k) . p_flag=l ; /*Look down*/ if (r== (crop_h-1)) p_flag=1 ; else if (crops [j+c+crop_w] ! =k) p_flag=1 ; if (p_flag==l) {distance=sqrt ((((double) c) - xbar) * ( ( (double) c)-xbar) + ( ( (double) r)-ybar) * ( ( (double) r) -ybar)) ; distance_sum=distance-sum+distance ; d_col = cs+c ; d row = rs+r ; perimeter-pixels [b [0]. spot_perimeter] = drow*w+dcol ; b [0]. spot_perimeter++ ; if (distance>b [0]. spot_rmax)

b [0]. spotrmax=distance ; if (distance<b [0]. spot_rmin) b [0]. spot_rmin=distance ; <BR> <BR> <BR> <BR> }<BR> <BR> <BR> if (b [0]. spotperimeter'=0) b [0]. spot_rbar=distance_sum/((double) b [0]. spot_perimeter) ; else b [0]. spot_rabar=0. 0 ; free (area) ; free (row max) ; free (row min) ; free (col_max) ; free (col-min) ; else {b [0]. spot_xbar= ((double) b [0]. box_column) ; b [0]. spot_ybar= ((double) b [0]. box-row) ; b [0]. spot_rbar=0. 0 ; b [0]. spot_rmin=0. 0 ; b [0]. spot_rmax=0. 0 ; b [0]. spot perimeter=0 ; b [0]. spot width=0 ; b [0]. spot height=0 ; getliststatistics (NULL, 0, &b [0]. spot) ; }

free (crop d) ; free (crop_s) ; return ; void get_largest_spot_average_position (struct image data *image, struct box * b, struct spot_finding_params *params) {int w, h, r, <BR> <BR> <BR> <BR> <BR> c,<BR> <BR> <BR> <BR> <BR> i,<BR> <BR> <BR> <BR> <BR> <BR> <BR> il k, crop, crop, rs, re, cs, ce, *crops, *area, *row max, *row min,

*col max, *colin, pflag ; unsigned, short int *d, *crop_d ; double xbar, ybar, distance, distance_sum ; w=image [0]. width ; h=image [0]. height ; d=image [0]. data ; crop region (b [0]. boxrow, b [0]. boxcolumn, w, h, d, &cropw, &croph, &cropd, &rs, &cs, &re, &ce, params) ; b [0]. threshold=set_threshold ((double) b [0]. box. average, (double) b [0]. small box. average, (double) b [0]. box. area, (double) b [0]. small_box. area, (double) params [0]. estimatedspotarea, (double) params [0]. fraction Ibar) ;

b [o]. num_spots=find_spots (crop_w, crop_h, crop_d, &crop_s, (int) b [0]. threshold, ( (int) MAX_INTENSITY), params [0]. furcation_type) ; if (b [0]. num_spots !=0) {area= (int *) malloc (sizeof (int) *b [0]. numspots) ; row_max= (int *) malloc (sizeof (int) *b [0]. numspots) ; row min= (int *) malloc (sizeof (int) *b [0]. num spots) ; col max= (int *) malloc (sizeof (int) *b [0]. numspots) ; col_min= (int *) malloc (sizeof (int) *b [0]. numspots) ; if ( (area==NULL) (row_max==NULL) (row_min==NULL) (col_max==NULL) (colmin==NULL)) {printf ("Failed malloc for'area'in get_largest_spot_average_position... \n") ; exit (-l) ; for (j=0 ; j<b [0]. numspots ; j++) row_max [j] =0 ; rowmin [j] =croph-l ; colmax [j] =0 ; col_min [j] =crop_w-1; area [j] =0 ;

for (r=0 ; r<crop_h ; r++) j=r*crop_w; for (c=0 ; c<crop_w c++) {i=crop-s [j+c] ; if (i>-l) area [i] ++ ; if (r>rowmax [i]) row_max [i] =r ; if (r<rowmin [i]) row_min [i] =r ; if (c>colmax [i]) col-max [i] =c ; if (c<colmin [i]) col_min [i] =c ; } k=0 ; for (j=0 ; j<b [0]. num-spots ; j++) if (area [j] >area [k]) k=j ; b [0]. spot_height-row_max [k] -row_min [k] +1 ; b [0]. spot_width =col_max [k] - col_min [k] +1 ; b [0]. spot. area=area [k] ;

/* Calculate spot morphology information based upon the spot selected above. */ i=0 ; xbar=0., 0 ; ybar=0. 0 ; for (r=rowmin [k] ; r< (row_max [k] +1) ; r++) {j=r*cropw ; for (c=col min [k] ; c< (col_max [k] +1) ; c++) if (crops [j+c] ==k) {xbar=xbar+ ( (double) c) ; ybar=ybar+ ( (double) r) ; i++ ; } else crop_s [j+c] =-l ; xbar=xbar/b [0]. spot. area ; ybar=ybar/b [0]. spot. area ; b [0]. spotxbar=xbar + ( (double) cs) ; b [0]. spot_ybar=ybar + ( (double) rs) ; b [0]. spot_rmax=0. 0 ; b [0]. spot_rmin= ((double) crop_w) * ( (double) crop_h) ; b [0]. spot-perimeter=0 ;

distance_wum=0. 0 ; for (r=rowmin [k] ; r< (row_max [k] +1) ; r++) {j=r*cropw ; for (c=col min [k] ; c< (col_max [k] +1) ; c++) if (crop_s[j+c] ==k) {flag=0 ; /*Look right */ if (c== (crop w-1)) p_flag=1 ; else if (crop_s [j+c+l] ! =k) p_flag=l ; /*Look left*/ if (c==0) p_flag=1 ; else if (crops [j+c-1] ! =k) p_flag=1 ; /*Look up*/ if (r==0) p_flag=1 ; else if (crop-s [j+c-crop_w] !=k) p_flag=l ;

/*Look down*/ if (r== (crop_h-1)) p_flag=l ; else if (crop_s [j+c+crop_w] ! =k) p_flag=l ; if (p_flag==l) { distance=sqrt ((((double) c)-xbar) * ( ( (double) c)-xbar) + ( ( (double) r)-ybar) * ( ( (double) r) -ybar)) ; distance_sum=distance_sum+distance ; b [0]. spot_perimeter++ ; if (distance>b [0]. spot_rmax) b [0]. spotrmax=distance ; if (distance<b [0]. spot-rmin) b [0]. spot_rmin=distance ; if (b [0]. spot perimeter ! =0) b [0]. spot_rabar=distance_sum/ ((double) b [0]. spot-perimeter) ; else b [0]. spot_rbar=0. 0 ; free (area) ; free (row max) ;

free (row_min) ; free (col_max) ; free (col-min) ; } else {b [0]. spot_xbar= ((double) b [0]. box_column) ; b [0]. spot ybar= ( (double) b [0]. box-row) ; b [0]. spot_rbar=0. 0 ; b [0]. spot rmin=0. 0 ; b [0]. spot_rmax=0. 0 ; b [0]. spot-perimeter=0 ; b [0]. spotwidth=0 ; b [0]. spot height=0 ; b [0]. spot. area=0 ; free (crop d) ; free (crop_s) ; return ; void get_largest_spot_pixels (struct image-data *image, struct box * b, struct spot_finding_params *params) {int w,

h, r, c, i, j, jprime, k, crop, crop, rs, re, cs, ce, *crops, *area, <BR> <BR> <BR> <BR> <BR> *row max,<BR> <BR> <BR> <BR> <BR> <BR> *row min,<BR> <BR> <BR> <BR> <BR> <BR> <BR> *col max, *col_min, num-spots ; unsigned short int *d, *crop_d ; w=image [0]. width ; h=image [0]. height ; d=image [0]. data ;

crop region (b [0]. box-row, b [0]. box column, w, h, d, &crop_w, &crop_h, &crop_d, &rs, &cs, &re, &ce, params) ; b [0]. threshold=set_threshold ((double) b [0]. box. average, (double) b [0]. small_box. average, (double) b [0]. box. area, (double) b [0]. small_box. area, (double) params [0]. estimated_spot_area, (double) params [0]. fraction Ibar) ; num_spots=find_spots (crop_W, crop_h, crop_d, &crop_s, (int) b [0]. threshold, ( (int) MAX-INTENSITY), params [0]. furcation-type) ; if (num-spots ! =0) {area= (int *) malloc (sizeof (int) *numspots) ; row_max= (int *) malloc (sizeof (int) *numspots) ; row min= (int *) malloc (sizeof (int) *numspots) ; col max= (int *) malloc (sizeof (int) *num-spots) ; col_min= (int *) malloc (sizeof (int) *numspots) ; if ( (area==NULL) (row_max==NULL) ##<BR> (row_min==NULL) ##<BR> (col_max==NULL) ##<BR> (colmin==NULL))

{printf ("Failed malloc for'area'in get_largestemacs_spot_statistics... \n") ; exit (-l) ; for (j=0 ; j<num_spots ; j++) {row_max [j] =0 ; rowmin [j] =croph-l ; col_max [j] =0 ; colmin [j] =cropw-l ; area [j] =0 ; for (r=0 ; r<croph ; r++) j=r*crop_w ; for (c=0 ; c<crop_w c++) {i=crop_s [j+c] ; if (i>-l) {area [i] ++ ; if (r>rowmax [i]) row_max [i] =r ; if (r<row_min [i]) row_min [i] =r ; if (c>col_max [i]) col_max [i] =c ; if (c<col_min [i]) col_min [i] =c ; }

k=0 ; for (j=0, ; j<numspots ; j++) if (area [j] >area [k]) k=j ; /* Calculate spot morphology information based upon the spot selected above. */ i=0 ; b [ol. spot. pixel_positions= (int *) malloc (sizeof (int) *area [k]) ; b [0]. spot. area=area [k] ; for (r=rowmin [k] ; r< (row_max [k] +1) ; r++) {j=r*crop_w ; jprime= (r+rs) *w ; for (c=colmin [k] ; c< (col_max [k] +1) ; c++) if (crops [j+c] ==k) {b [0]. spot. pixel_positions [i] =jprime+c+cs ; i++ ; free (area) ; free (row max) ;

free (row min) ; free (col max) ; free (col-min) ; } else, {b [0]. spot. area=0 ; b [0]. spot. pixel_positions=NULL ; free (crop d) ; free (crops) ; return ; find-spots. c #include"defs. h" /* Calculate threshold level for spot finding in a box.

The threshold is calculated based upon spot and background intensities. Those intensitities are obtained from average intensities within boxes of two different sizes and knowning the approximate area of a spot. The threshold is a rules of mixture of intensity between spot and background levels.

If this calculation fails, for example if the spot

intensity is found to be negative, the function defaults to the programs former behavior.

*/ unsigned short int set_threshold (double i_bb, double isb, double area_bb, double areas, double area-spot, double fraction) {double i_spot, ibg, temp ; temp=areabb-areasb ; if (temp>0. 0) i_bg= (i_bb*area_bb-i_sb*area_sb) /temp ; if ((i_bg>0. 0) && (areaspot>0. 0)) {i_spot= (ibb*areabb- (areabb-areaspot) *ibg)/areaspot ; if ((i_spot>0. 0) && (ispot>ibg)) return ( (unsigned short int) (ibg + 0. 5*fraction* (ispot-ibg))) ;

return ( (unsigned short int) (fraction*ibb)) ; } void trifurcate (int r, int c, int w, int h, int *s, int sn, int type) {int i, sd=0 ; struct stack {int r, c ; char re ; } *stk ; stk= (struct stack *) malloc (sizeof (struct stack) *w*h) ; if (stk==NULL) {printf ("Failed to allocate the stack in trifurcate... \n") ; exit (0) ; i=r*w+c ;

top : /* Left */ if (c>o), if (s [i-l] ==type) {s [i-l] =sn ; /* Push onto stack */ stk [sd]. r=r ; stk [sd]. c=c ; stk [sd]. re='r'; c-- ; i-- ; sd++ ; goto top ; right : /* Right */ if (c< (w-l)) if (s [i+l] ==type) s [i+l] =sn ; /* Push onto stack */ stk [sd]. r=r ; stk [sd]. c=c ;

stk [sd]. re='u' ; C++ ; i++ ; sd++ ; goto, top ; up : /* Up */ if (r>0) if (s [i-w] ==type) s [i-w] =sn ; /* Push onto stack */ stk [sd]. r=r ; stk [sd]. c=c ; stk [sd]. re='d' ; r-- ; i=i-w ; sd++ ; goto top ; down : /* Down */ if (r< (h-l))

if (s [i+w] ==type) {s [i+w] =sn ; /* Push onto stack */ stk [sd]. r=r ; stk [sd]. c=c ; stk [sd]. re='e' ; r++ ; i=i+w ; sd++ ; goto top ; end : if (sd==0) {free (stk) ; return ; else {/* Pop the stack */ sd-- ; r=stk [sd]. r ; c=stk [sd]. c ; i=r*w+c ; if (stk [sd]. re=='r'_ goto right ;

if (stk [sd]. re=='d') goto down ; if (stk [sd]. re=='u') goto up ; goto end ; int find-spots-simple (int w, int h, unsigned short int *d, int *s, unsigned short int bl, unsigned short int bh) {int r, c, j, n, sn=0 ; n=h*w ; for (j=0 ; j<n ; j++) {if ((d [j] >=bl) && (d [j] <=bh)) s [j] =UNIDENTIFIED ; if (d [j] <bl) s [j] =TOO LOW ; if (d [j] >bh) s [j] =TOO HIGH ;

for (r=0 ; r<h ; r++) {j=r*w ; for (c=0 ; c<w ; c++) if (s [j+c] ==UNIDENTIFIED) {s [j, +c] =sn ; trifurcate (r, c, w, h, s, sn, UNIDENTIFIED) ; sn++ ; return (sn) ; } int find spots edgereject holefill (int w, int h, unsigned short int *d, int *s, unsigned short int bl, unsigned short int bh) {int r, c, j, n, sn=0, numtruespots=0, * defect ; /* Classify points as to bracketing */ n=h*w ; for (j=0 ; j<n ; j++)

if ( (d [j] >=bl) && (d [j] <=bh)) s [j] =INSIDE ; else s [j] =OUTSIDE ; /* Scan the edges */ r=0 ; c=0 ; for (c=0 ; c<w ; c++) {if (s [c] ==INSIDE) trifurcate (r, c, w, h, s, EDGE, INSIDE) ; if (s [c] ==OUTSIDE) trifurcate (r, c, w, h, s, EDGE, OUTSIDE) ; c=O ; for (r=l ; r<h ; r++) {j=r*w+c ; if (s [j] ==INSIDE) trifurcate (r, c, w, h, s, EDGE, INSIDE) ; if (s [j] ==OUTSIDE) trifurcate (r, c, w, h, s, EDGE, OUTSIDE) ; } c=w-l ; for (r=l ; r<h ; r++) {j=r*w+c ; if (s [j] ==INSIDE)

trifurcate (r, c, w, h, s, EDGE, INSIDE) ; if (s [j] ==OUTSIDE) trifurcate (r, c, w, h, s, EDGE, OUTSIDE) ; r=h-1 ; for (c=l ; c<w ; c++) {j=r*w+c ; if (s [j]==INSIDE) trifurcate (r, c, w, h, s, EDGE, INSIDE) ; if (s [j] ==OUTSIDE) trifurcate (r, c, w, h, s, EDGE, OUTSIDE) ; for (j=0 ; j<n ; j++) if (s [j] ==OUTSIDE) s [j] =INSIDE ; for (r=l ; r< (h-l) ; r++) {j=r*w ; for (c=l ; c< (w-l) ; c++) if (s [j+c] ==INSIDE) s [j+cl=sn ; trifurcate (r, c, w, h, s, sn, INSIDE) ; sn++ ;

/* For edgerejectholefill, can produce defect spots under certain circumstances which must be removed. */ /* First, step, find the spots that are defective */ if (sn>0) defect= (int *) malloc (sn * sizeof (int)) ; if (defect==NULL) {printf ("Failed malloc for defect in find_spots_edgereject_holefill... \n") ; exit (-l) ; /* Assume the spot is defective */ for (j=0 ; j<sn ; j++) defect [j] =l ; /* If the spot contains at least one pixel in the threshold range it is not defective */ for (j=o ; j<n ; j++) if ((d [j] >=b1) && (d [j] <=bh)) if ( (s [j] > (-l)) && (s [j] <sn)) defect [s [j]] =0 ;

/* Now let's rename the spots to remove the defects.

This may be confusing, but for the sake of speed, the defect array will also be used to rename spots. */ /* If a spot is not defective it is given a proper name.

If it is defect it is set equal to EDGE type for now. */ for (j=0 ; j<sn ; j++) if (defect [j] ==0) { defect [j] =num_true_spots ; numtruespots++ ; else {defect [j] =EDGE ; /* Assign pixels the proper spot name based on it defect name */ for (j=0 ; j<n ; j++) {if (sEj] > (-l)) s [j] =defect [s [j]] ; if (s [j] ==EDGE) {if (d [j] <bl) s [j] =TOO LOW ;

if (d [j] >bh) s [j] =TOO_HIGH ; free (defect) ; return (numtruespots) ; else {for (j=0 ; j<n ; j++) if (s [j] ==EDGE) {if (d [j] <bl) s [j] =TOO_LOW ; if (d [j] >bh) s [j] =TOO_HIGH ; return (0) ; int find_spots_edgereject_holefill_old (int w, int h, unsigned short int *d, int *s, unsigned short int bl,

unsigned short int bh) {int r, c, j, n, sn=0 ; /* Classify points as to bracketing */ n=h*w ; for (j=0 ; j<n ; j++) if ( (d [j] >=bl) && (d [j] <=bh)) s [j] =INSIDE ; else s [j] =OUTSIDE ; /* Scan the edges */ r=0 ; c=0 ; for (c=0 ; c<w ; c++) {if (s [c] ==INSIDE) trifurcate (r, c, w, h, s, EDGE, INSIDE) ; if (s [c] ==OUTSIDE) trifurcate (r, c, w, h, s, EDGE, OUTSIDE) ; } c=O ; for (r=l ; r<h ; r++) {j=r*w+c ; if (s [j] ==INSIDE)

trifurcate (r, c, w, h, s, EDGE, INSIDE) ; if (s [j] ==OUTSIDE) trifurcate (r, c, w, h, s, EDGE, OUTSIDE) ; c=w-l ; for (r=l ; r<h ; r++) j=r*w+c ; if (s [j] ==INSIDE) trifurcate (r, c, w, h, s, EDGE, INSIDE) ; if (s [j] ==OUTSIDE) trifurcate (r, c, w, h, s, EDGE, OUTSIDE) ; r=h-l ; for (c=l ; c<w ; c++) {j=r*w+c ; if (s [j] ==INSIDE) trifurcate (r, c, w, h, s, EDGE, INSIDE) ; if (s [jl==OUTSIDE) trifurcate (r, c, w, h, s, EDGE, OUTSIDE) ; for (j=0 ; j<n ; j++) if (s [j] ==OUTSIDE) s [j] =INSIDE ; for (r=l ; r< (h-l) ; r++)

{j=r*w ; for (c=l ; c< (w-l) ; c++) if (s [j+c] ==INSIDE) {s [j+c] =sn ; trifurcate (r, c, w, h, s, sn, INSIDE) ; sn++ ; } for (j=0 ; j<n ; j++) if (s [j] ==EDGE) if (d [j] <bl) s [j] =TOO LOW ; if (d [j] >bh) s [j] =TOO HIGH ; return (sn) ; int find_spots_holefill (int w, int h, unsigned short int *d, int *s, unsigned short int bl, unsigned short int bh) {int r, c, j, n, sn=0 ;

/* Classify points as to bracketing */ n=h*w ; for (j=0 ; j<n ; j++) if ((d [j,], =bl) && (d [j] <=bh)) s [j] =INSIDE ; else s [j] =OUTSIDE ; /* Scan the edges */ r=0 ; c=0 ; for (c=0 ; c<w ; c++) if (s [c] ==OUTSIDE) trifurcate (r, c, w, h, s, EDGE, OUTSIDE) ; c=O ; for (r=l ; r<h ; r++) {j=r*w+c ; if (s [j] ==OUTSIDE) trifurcate (r, c, w, h, s, EDGE, OUTSIDE) ; c=w-l ; for (r=l ; r<h ; r++) {j=r*w+c ; if (s [j] ==OUTSIDE) trifurcate (r, c, w, h, s, EDGE, OUTSIDE) ;

r=h-1 ; for (c=l ; c<w ; c++) {j=r*w+c ; if (s [j] ==OUTSIDE) trifurcate (r, c, w, h, s, EDGE, OUTSIDE) ; for (j=0 ; j<n ; j++) if (s [j] ==OUTSIDE) s [j] =INSIDE ; for (r=l ; r< (h-l) ; r++) {j=r*w ; for (c=l ; c< (w-l) ; c++) if (s [j+c] ==INSIDE) {s [j+c] =sn ; trifurcate (r, c, w, h, s, sn, INSIDE) ; sn++ ; for (j=0 ; j<n ; j++) if (s [j] ==EDGE) if (d [j] <bl) s [j] =TOO LOW ; if (d [j] >bh) s [j] =TOO-HIGH ;

return (sn) ; int find spots edgereject (int w, int h, unsigned short int *d, int *s, unsigned short int bl, unsigned short int bh) {int r, c, j, n, sn=0 ; /* Classify points as to bracketing */ n=h*w ; for (j=0 ; j<n ; j++) if ((d [j] >=b1) && (d [j] <=bh)) s [j] =INSIDE ; else s [j] =OUTSIDE ; /* Scan the edges */ r=0 ; c=0 ; for (c=0 ; c<w ; c++) if (s [c] ==INSIDE) trifurcate (r, c, w, h, s, EDGE, INSIDE) ;

c=0; for (r=l ; r<h ; r++) {j=r*w+c ; if (s [j] == INNSIDE) trifurcate (r, c, w, h, s, EDGE, INSIDE) ; c=w-l ; for (r=l ; r<h ; r++) {j=r*w+c ; if (s [j] ==INSIDE) trifurcate (r, c, w, h, s, EDGE, INSIDE) ; r=h-1 ; for (c=l ; c<w ; c++) j=r*w+c ; if (s [j] ==INSIDE) trifurcate (r, c, w, h, s, EDGE, INSIDE) ; for (r=l ; r< (h-l) ; r++) {j=r*w ; for (c=l ; c< (w-l) ; c++) if (s [j+c] ==INSIDE) {s [j+c] =sn ; trifurcate (r, c, w, h, s, sn, INSIDE) ; sn++ ;

for (j=0 ; j<n ; j++) if (s [j], ==EDGE) {if (d[j] <b1) s [j] =TOO_LOW ; if (d [j] >bh) s [j. ]=TOO_HIGH ; } return (sn) ; int find-spots (int w, int h, unsigned short int * d, int ** s, int bl, int bh, int furcation_type) if ((b1>=0) && (b1<=MAX_INTENSITY) && (bh>=0) && (bh<=MAX INTENSITY)) {s [0] = (int *) malloc (sizeof (int) * w * h) ; if (s [0] ==NULL) {printf ("Failed malloc for s [0] inf find_spots... \n") ;

exit (-l) ; if (furcationtype==HOLEFILL) return (find spots holefill (w, h, d, s [0], ( (unsigned short int) bl), ( (unsigned short int) bh))) ; if (furcation type==SIMPLE) return (findspotssimple (w, h, d, s [0], ( (unsigned short int) bl), ( (unsigned short int) bh))) ; if (furcationtype==EDGEREJECTHOLEFILL) return (find_spots_edgereject_holefill (w, h, d, s [0], ( (unsigned short int) bl), ( (unsigned short int) bh))) ; if (furcationtype==EDGEREJECT) return (findspotsedgereject (w, h, d, s [0], ( (unsigned short int) bl), ( (unsigned short int) bh))) ; else {printf ("Error, a threshold intesity is out of range... \n") ;

printf ("lower threshold intensity= i upper threshold intensity=%i\n", bl, bh) ; exit (-l) ; return (0) ; void threshold-image (struct image data *image, unsigned short int bl, unsigned short int bh) {int *s, i, n ; n=image [0]. width*image [0]. height ; s= (int *) malloc (sizeof (int) *n) ; if (s==NULL) {printf ("Failed malloc in find_spots... \n") ; exit (-l) ; } image [0]. numboxes=findspotsedgerejectholefill (image [0]. width, image [0]. height, image [0]. data, s, bl, bh) ;

image [0]. boxes= (struct box *) malloc (image [0]. num_boxes*sizeof (struct box)) ; printf ("%ni\n", image [0]. numboxes) ; /* Initialize all box structure members */ for (i=0 ; i<image [0]. numboxes ; i++) {getliststatistics (NULL, 0, &image [0]. boxes [i]. spot) ; get list statistics (NULL, 0, &image [0]. boxes [i]. box) ; get_list_statistics (NULL, 0, &image [0]. boxes [i]. background) ; image [0]. boxes [i]. spot xbar=0. 0 ; image [0]. boxes [i]. spotybar=0. 0 ; for (i=0 ; i<n ; i++) if (s [i] > (-l)) {image [0]. boxes [s [i]]. spot. area++ ; image [0]. boxes [s [i]]. spot xbar= ( (double) (i%image[0]. width)) + image [0]. boxes [s [i]]. spot_xbar ; image [0]. boxes [s [i]]. spot_ybar=((double) (i/image [0]. width)) + image [0]. boxes [s [i]]. spot ybar ; image [0]. boxes [s [i]]. spot. median=image [0]. boxes [s [i]]. s pot. median + ( (double) image [0]. data [i]) ;

for (i=0 ; i<image [0]. numboxes ; i++) image [0]. boxes [i]. spotxbar=image [0]. boxes [i]. spotxbar / ( (double) image [0]. boxes [i]. spot. area) ; image [0]. boxes [i]. spot_ybar=image [0]. boxes [i]. spot ybar / ((double) image [0]. boxes [i]. spot. area) ; image [0]. boxes [i]. box-column= ( (int) (image [0]. boxes [i]. spot xbar+0. 5)) ; image [0]. boxes [i]. box_row = ( (int) (image [0]. boxes [i]. spot_ybar+0. 5)) ; image [0]. boxes [i]. spot. median=image [0]. boxes [i]. spot. me dian/ ( (double) image [0]. boxes [i]. spot. area) ; image [0]. boxes [i]. spot. average=image [0]. boxes [i]. spot. m edian ; /* printf ("xbar=%e ybar=ke c=%6i r=%6i area=%6i\n", image [0]. boxes [i]. spot-xbar, image [0]. boxes [i]. spot_ybar, image [0]. boxes [i]. box_column, image [0]. boxes [i]. box-row, image [0]. boxes [i]. spot. area) ;

*/ } free (s) ; } free-image. c #include"defs. h" void free-box (struct box * this-box) if (thisbox->wrtreference ! =NULL) { if (this_box->wrt_reference->spot.pixel_positions!=NULL) free (thisbox->wrtreference->spot. pixelpositions) ; free (thisbox->wrtreference) ; if (thisbox->reference ! =NULL) { if (this_box->reference->spot.pixel_positions!=NULL) free (thisbox->reference->spot. pixelpositions) ; free (thisbox->reference) ; if (this_box->common!=NULL) if (this_box->common->spot.pixel_positions!=NULL) free (thisbox->common->spot. pixelpositions) ; free (thisbox->common) ;

void free-image (struct image data * image) { int i ; if (image ! =NULL) if (image->image_description ! =NULL) { free (image->image_description) ; image->image_description=NULL ; if (image->image_name!=NULL) free (image->imagename) ; image_>image_name=NULL ; if (image->data ! =NULL) free (image->data) ; image->data=NULL ; if (image->integrateddata ! =NULL) free (image->integrateddata) ; image- >integrated_data=NULL ; if (image->boxes ! =NULL) {

for (i=0 ; i<image->numboxes ; i++) { free-box (&image->boxes [i]) ; free (image->boxes) ; image-, >boxes=NULL ; free (image) ; image=NULL ; } info. c #include"defs. h" void credits () printf ("ArrayExpress\n") ; printf ("by Cameron Tanner and Patrick Tepesch\n") ; printf ("Copyright Corning Incorporated\n") ; printf ("Patent pending\n") ; printf ("Version") ; printf (EXPRESS ARRAY VERSION) ; printf (" Released January, 2001. \n") ;

void check command line (int argc, char *argv []) { FILE *f ; if (argc<3) {printf ("For image analysis : \n") ; printf ("'wspots printer filename imagel. tif image2. tif... imageN. tif\n") ; printf ("To generate a template options file called printer. txt : \n") ; printf (" wspots p\n") ; if ( (argc==2) && (argv [l] [0] =' ?')) {f=fopen ("printer. txt","w") ; if (f ! =NULL) {fprintf (f,"l\tspots per row\n") ; fprintf (f,"l\tspots per column\n") ; fprintf (f,"l\tpins per row\n") ; fprintf (f,"l\tpins per column\n") ; fprintf (f, "1\tspot diameter\n") ; fprintf (f,"l\tspot pitch\n") ; fprintf (f,"l\tpin pitch rows\n") ; fprintf (f,"l\tpin pitch columns\n") ; fprintf (f,"l\torigin row\n") ; fprintf (f,"l\torigin column\n") ; fprintf (f,"l\tpin rattle\n") ; fprintf (f,"l\tax\n") ; fprintf (f, "1\tay\n") ; fprintf (f, "1\tbox\n") ; fprintf (f,"l\tby\n") ;

fprintf (f,"l\tcx\n") ; fprintf (f,"l\tcy\n") ; fprintf (f, "1\tdx\n") ; fprintf (f,"l\tdy\n") ; fprintf (f, "1\tfind boxes limit furcation\n") ; fprintf (f, "1\tfind boxes limit center\n") ; fprintf (f,"l\tfind boxes fraction by furcation\n") ; fprintf (f, "1. 0\tfind boxes center tolerance\n") ; fprintf (f,"l\tfind boxes spot params crop width\n") ; fprintf (f,"l\tfind boxes spot params crop height\n") ; fprintf (f,"simple\tfind boxes spot params furcation type\n") ; fprintf (f,"holefill\n") ; fprintf (f,"edgereject\n") ; fprintf (f,"edgerejecthollfill\n") ; fprintf (f,"1. 0\tfind boxes spot params fraction Ibar\n") ; fprintf (f,"l\tcenter boxes limit center\n") ; fprintf (f,"1. 0\tcenter boxes center tolerance\n") ; fprintf (f,"l\tcenter boxes spot params crop width\n") ; fprintf (f,"l\tcenter boxes spot params crop height\n") ;

fprintf (f,"simple\tcenter boxes spot params furcation type\n") ; fprintf (f,"holefill\n") ; fprintf (f,"edgereject\n") ; fprintf (f,"edgerejecthollfill\n") ; fprintf (f,"1. 0\tcenter boxes spot params fraction Ibar\n") ; fprintf (f,"l\tdraw perimeter spot params crop width\n") ;. fprintf (f,"l\tdraw perimeter spot params crop height\n") ; fprintf (f,"simple\tdraw perimeter spot params furcation type\n") ; fprintf (f,"holefill\n") ; fprintf (f,"edgereject\n") ; fprintf (f,"edgerejecthollfill\n") ; fprintf (f,"on/off\tdraw perimeter debug\n") ; fprintf (f,"1. 0\tdraw perimeter spot params fraction Ibar\n") ; fprintf (f,"l\tcrop image data spot params crop width\n") ; fprintf (f,"l\tcrop image data spot params crop height\n") ; fprintf (f,"simple\tcrop image data spot params furcation type\n") ; fprintf (f,"holefill\n") ; fprintf (f,"edgereject\n") ; fprintf (f,"edgerejecthollfill\n") ;

fprintf (f,"1. 0\tcrop image data spot params fraction Ibar\n") ; fprintf (f,"on/off\toutput image tiff zip\n") ; fprintf (f,"on/off\toutput image tiff jpg\n") ; fpr, intf (f,"on/off\toutput image jpg\n") ; fprintf (f,"on/off\toutput image ppm\n") ; fprintf (f,"on/off\toutput image grid\n") ; fprintf (f,"on/off\toutput image perimeter\n") ; fprintf (f,"on/off\toutput image integrated\n") ; fprintf (f,"l\toutput image jpg quality\n") ; fprintf (f,"./\toutput image path\n") ; fprintf (f,"on/off\tintegration square\n") ; fprintf (f,"on/off\tintegration circle\n") ; fprintf (f,"l. 0\tintegration radius\n") ; fprintf (f,"l\tintegration width\n") ; fprintf (f,"l\tintegration height\n") ; fprintf (f,"on/off\tintegration out square\n") ; fprintf (f,"on/off\tintegration out circle\n") ; fprintf (f,"1. 0\tintegration out radius\n") ; fprintf (f,"l\tintegration out width\n") ; fprintf (f,"l\tintegration out height\n") ; fprintf (f,"on/off\tfind angles do find angles\n") ; fprintf (f,"l\tfind angles iteration limit\n") ; fprintf (f,"0. 1\tfind angles x-vector tolerance\n") ; fprintf (f,"0. 1\tfind angles y-vector tolerance\n") ;

fprintf (f,"0. 01\tfind angles convergence distance\n") ; fprintf (f,"on/off\tmap spots do coarse\n") ; fprintf (f,"on/off\tmap spots do fine\n") ; fprintf (f,"on/off\tmap spots do pin by pin\n") ; fprintf (f,"on/off\tmap spots do distance\n") ; fprintf (f,"l\tmap spots increment coarse\n") ; fprintf (f,"l\tmap spots increment fine\n") ; fprintf (f,"l\tmap spots increment pin by pin\n") ; fprintf (f,"l\tmap spots increment distance\n") ; fprintf (f,"l\tmap spots range fine row\n") ; fprintf (f,"l\tmap spots range fine column\n") ; fprintf (f,"l\tmap spots range pin by pin row\n") ; fprintf (f,"l\tmap spots range pin by pin col\n") ; fprintf (f,"l\tmap spots range distance row\n") ; fprintf (f, "1\tmap spots range distance column\n") ; fprintf (f,"l\tmap spots debug\n") ; fprintf (f,"on/off\tbackground square\n") ; fprintf (f,"on/off\tbackground circle\n") ; fprintf (f,"l\tbackground frame width\n") ; fprintf (f,"l\tbackground radius\n") ; fclose (f) ;

exit (0) ; integrate_regions.c #include"defs. h" void spot-statistics-common (struct image-data * image, struct image data * ref_image, int * pixel positions, int num_pixels, struct overlap * oimage, struct statistics * stats, struct statistics * ratio_stats) { int *pp, np, i ; unsigned short int * pi ; double * log_ratio ; if (numpixels<l) { getdliststatistics (NULL, 0, ratio_stats) ; get list statistics (NULL, 0, stats) ; else if (oimage ! =NULL) if ((oimage->width==image->width && (oimage->height==image->height)) { np=num_pixels ;

pp= (int *) malloc (np*sizeof (int)) ; if ( (pp==NULL)) {printf ("Failed malloc for pp in spot_statistice_common..\n"); exit t(-1); for (i=0 ; i<np ; i++) pp [i] =pixelpositions [i] ; filter_list_by_pixel_attribute (oimage, &pp, &np, SATURATED PIXEL) ; /*this protects against a 0 length malloc on the dec*/ if (np>0) { log_ratio= (double *) malloc (np*sizeof (double)) ; pi= (unsigned short int *) malloc (np*sizeof (unsigned short int)) ; if ( (logratio==NULL))) (pi==NULL)) {printf ("Failed malloc for log ratio in spot_statistics_common... \n") ; exit (-l) ; for (i=0 ; i<np ; i++) { pi [i] =image->data [pp [i]] ; if (pi [i] ==o)

log_ratio[i]=-DBL_MAX ; else if (ref_image->data [pp [i]] ==0) logratio [i] =DBLMAX ; else log_ratio[i]=log ( (double) (pi [i])/ (double) (refimage->data [pp [i]])) ; getdliststatistics (logratio, np, ratio_stats) ; get-list-statistics (pi, np, stats) ; free (pi) ; free (log-ratio) ; else { getdliststatistics (NULL, 0, ratio_stats) ; get_list_statistics (NULL, 0, stats) ; } free (pp) ; else printf ("Size of overlap image does not match image... \n") ; } else printf ("Where is the overlap image ? \n") ; void integrate_boxes (struct image-data * image, struct integration_params * iparams)

int box ; for (box=o ; box<image->numboxes ; box++) integrate_region (image, iparams, image->boxes [box]. boxro w, image->boxes [box]. box_column, &image->boxes [box]. box) ; void get mask pixels (struct image data * image, int row, int col, int mask-width, double * mask, int * num_pixels, int * mask_pixels) int sub-row, sub-col, pixel, even, odd, mask_point, w, h ;

w=image->width ; h=image->height ; num_pixels[0]\0 ; even = (int) ( (double) (mask_width/2) - ((double) mask_width/2.0)+1.1); if (even==0) odd=l ; else odd=0 ; mask_point=0 ; for (subrow=row-maskwidth/2 ; (subrow< (row+maskwidth/2+odd)) ; sub_row++) for (subcol=col-maskwidth/2 ; (subcol< (col+maskwidth/2+odd)) ; sub_col++) pixel = subrow*w+subcol ; if ( ! ((sub_row<0) ## (sub_col<0) ## (sub_row>=h) ## (sub_col>=w) ## (pixel)>=w*h) ) ) { if (mask [mask_point]>0. 0) { mask_pixels [num_pixels [0]] =pixel ; num_pixels [0] ++ ; mask_point++ ;

void getmaskpixelsintensities (struct image data * image, int row, int col, int mask-width, double * mask, int num_pixels, int * mask-pixels, unsigned short int * mask pixel-intensities) int j, even, odd, mask_point, w, h, imrow, imcol, mask-row, mask col ; w=image->width ; h=image->height ; even = (int) ( (double) (mask_width/2) - ((double) mask_width/2. 0) +1. 1) ;

if (even==0) odd=l ; else odd=0 ; maskpoint=0 ; for (j=0 ; j<numpixels ; j++) {imrow=mask_pixels [j]/w ; imcol=maskpixels [j] %w ; if ((imrow>(-1)) && (imcol> (-1)) && (imrow<image->height) && (imcol<image->width)) {maskrow=imrow- (row-maskwidth/2) ; maskcol=imcol- (col-maskwidth/2) ; if ((mask_row> (-1)) && (mask_col>(-1)) && (maskrow<maskwidth) && (maskcol<maskwidth)) mask_pixel_intensities [j] = (unsigned short int) ( ( (double) image [0]. data [mask_pixels [j]]) *mask [maskrow*maskwidth +maskcol] + 0. 5) ; else printf ("Warning, asking for mask pixels exceeding mask_width\nmask_width=%i mask_row=%i mask_col=%i row=%i col=%i imrow=%i imcol=%i\n", mask_width, mask-row, mask-col, row, col, imrow, imcol) ; else

printf ("Warning pixel in list is out of bounds for image imrow=%i imcol=Wi... \n", imrow, imcol) ; void integrateregionmask (struct image data * image, int row, int col, int mask-width, double * mask, struct statistics * stats) int mask-area, num ixels, * pixel positions ; unsigned short int * pixel-intensities ; maskarea=maskwidth*maskwidth ; pixel-positions= (int *) malloc (sizeof (int) *maskara) ; pixel_intensities= (unsigned short int *) malloc (sizeof (unsigned short int) *maskara) ; if ((pixel_positions==NULL) # (pixel_intensities==NULL))

{printf ("Failed malloc for either pixel-positions or pixel-intensities in integrate_region_mask... \n") ; exit (-l) ; get mask pixels (image, row, col, mask-width, mask, &num_pixels, pixel positions) ; gtet_mask_pixels_intensities (image, row, col, mask_width, mask, num_pixels, pixel_positions, pixel_intensities) ; get_list_statistics (pixel-intensities, num_pixels, stats) ; free (pixel_positions) ; free (pixel-intensities) ; void get_region_pixels (struct image data * image, struct integration_params * iparams, int row, int col, int _pixels, int * pixel positions) {int w, h,

r-int, sub-row, sub-col, region, pixel ; if (iparams->mask_flag==1) get mask pixels (image, row, col, iparams->maskwidth, iparams->mask, num_pixels, pixel positions) ; else w = image->width ; h = image->height ; point = iparams->integrationradius ; region=row*w+col ; subrow=row- (rint-l) ; if (subrow<0) sub row=0 ; num_pixels [0] =0 ; while ((sub_row<h) && (subrow<= (row+ (r_int-1)))) {subcol=col- (rint-l) ; if (subcol<0) sub col=0 ; while ((sub_col<w) && (subcol<= (col+ (r int-1))) pixel=sub_row*w+sub_col ; pixel_positions [num_ppixels[0]]=pixel ;

sub_col++ ; numpixels [0] ++ ; sub_row++ ; } } } void integrate region (struct image-data * image, struct integration_params * iparams, int row, int col, struct statistics * stats) {int num_pixels, outer-radius, i, *pixel-positions ; unsigned short int * pixel-intensities ; if ((iparams->mask_flag==1)) pixel_positions= (int *) malloc (iparams->maskwidth*iparams->maskwidth*sizeof (i nt)) ; pixel-intensities= (unsigned short int *) malloc (iparams->maskwidth*iparams->maskwidth*sizeof (u nsigned short int)) ; if ((pixel_positions==NULL)) (pixel_intensities==NULL))

{printf ("Failed malloc for pixel-positions or pixel_intensities in integrate region... \n") ; exit (-l) ; getmaskpixels (image, row, col, iparams->maskwidth, iparams->mask, &numpixels, pixel_positions) ; getmaskpixelsintensities (image, row, col, iparams->maskwidth, iparams->mask, numpixels, pixel positions, pixel-intensities) ; } else { outer_radius=iparams->integration_radius ; pixel-positions= (int *) malloc ((2*outer_radius+1) * (2*outer radius+1) *sizeof (int )) ; pixel-intensities= (unsigned short int *) malloc ((2*outer_radius+1) * (2*outer radius+1) *sizeof (uns igned short int)) ; get-region pixels (image, iparams, row, col, &num_ppixels, pixel positions) ; for (i=0 ; i<numpixels ; i++) pixel-intensities [i]=image->data[pixel_positions[i]] ;

getliststatistics (pixelintensities, numpixels, stats) ; free (pixel_positions) ; free (pixel_intensities) ; void integrate_region_common (struct image data * image, struct integration_params* iparams, int row, int col, struct statistics * stats, struct overlap *oimage) int num_pixels, outer_radius, i, *pixel_positions ; unsigned short int * pixel-intensities ; if (oimage ! =NULL) { if ((oimage->width==image->width) && (oimage->height==image->height)) if ((iparams->mask_flag==1)) { pixel_positions= (int *) malloc (iparams->maskwidth*iparams->maskwidth*sizeof (i nt)) ; pixel_intensities= (unsigned short int *)

malloc (iparams->maskwidth*iparams->maskwidth*sizeof (u nsigned short int)) ; if ((pixel_positions==NULL) (pixelintensities==NULL)).

{printf ("Failed malloc for pixel_positions or pixel intensities in integrate region... \n") ; exit (-l) ; get mask pixels (image, row, col, iparams->maskwidth, iparams->mask, &num_pixels, pixel positions) ; filterlistbypixelattribute (oimage, &pixel_positions, &num_pixels, SATURATED_PIXEL) ] ; get mask-pixels-intensities (image, row, col, iparams->maskwidth, iparams->mask, num_pixels, pixel_positions, pixel-intensities) ; else { outer_radis=iparams->integration_radius ; pixel_positions= (int *) malloc ((2*outer_radius+1) * (2*outer radius+1) *sizeof (int )) i

pixel intensities= (unsigned short int *) malloc ((2*outer_radius+1) * (2*outer radius+1) *sizeof (uns igned short int)) ; get_region_pixels (image, iparams, row, col, &num_pixels, pixel_positions) ; for (i=0 ; i<num_pixels ; i++) pixel_intensities [i]=image->data[pixel_positions ; ; filterlistbypixelattribute (oimage, _ &pixel_positions, &numpixels, SATURATEDPIXEL) ; get-list-statistics (pixel_intensities, num_pixels, stats) ; free (pixel_positions) ; free (pixel-intensities) ; else printf ("Size of the overlap image does not match the image... \n") ; else printf ("Where is the overlap image ? \n") ; } Integrated * integrate regions (struct image data * image,

struct integration params * iparams) if ((iparams-omask_flag==l)) return (integrate regions mask (image->data, image->width, image->height, iparams->maskwidth, iparams->mask)) ; else/*if ((iparams->square_flag==l)) */ return (integrateregionsrectanglefast (image->data, image->width, image->height, iparams->integrationwidth, iparams->integrationheight)) ; double integrate region rectangle-slow (struct image data * image, int row, int col, int a, int b) {unsigned short int * data ; int w, h, r_int, sub-row, sub-col, pixel, area ; double intensity ;

data = image->data ; w = image->width ; h = image->height ; r int = a ; subrow=row- (rint-l) ; if (subrow<0) sub row=0 ; area=0 ; intensity=0. 0 ; while ((sub_rowh) && (subrow<= (row+ (rint-l)))) sub-col=col- (r-int-1) ; if (subcol<0) sub col=0 ; while ((sub_col<w) && (subcol<= (col+ (rint-l)))) { pixel=sub_row*w+sub_col ; intensity=intensity+data [pixel] ; sub_col++ ; area++ ; sub_row++ ; } return (intensity) ; Integrated * integrate regions rectangle-fast (unsigned short int * d, int w,

int h, int a, int b) {int cr, cc, r, c, wx, wy, i, j ; Integrated *integrated, primer, *col, area-max ; integrated= (Integrated *) malloc (sizeof (Integrated) *w*h) ; if (integrated==NULL) {printf ("Failed malloc for integrated in function integrate... \n") ; exit (-l) ; col= (Integrated *) malloc (sizeof (Integrated) *w) ; if (col==NULL) {printf ("Failed malloc for col in function integrate... \n") ; exit (-l) ; cr=b-l ; cc=a-1 ; wx=2* (a-1) +l ; wy=2* (b-1) +l ;

for (r=0 ; r<h ; r++) for (c=0 ; c<w ; c++) integrated [r*w+c] =0. 0 ; for (c=0 ;, c<w ; c++) col [c]=0.0 ; for (r=0 ; r< (wy-cr) ; r++) {i=r*w ; for (c=0 ; c<w ; c++) col [c]=col[c] | ((Integrated) d[i+c]) ; primer=0. 0 ; for (c=0 ; c< (wx-cc) ; c++) primer=primer+col [c] ; integrated [0] =primer ; /* Top row */ for (c=l ; c<=cc ; c++) integrated [c] =integrated [c-l] +col [c+cc] ; for (c= (cc+l) ; c< (w-cc) ; c++) integrated [c]=integrated [c-1]+col[c+cc]-col[c-cc-1] ;

for (c= (w-cc) ; c<w ; c++) integrated [c]=integrated [c-1]-col[c-cc-1]; for (r=l ; r<=cr ; r++) {j=r*w ;, integrated [j] =integrated [j-w] ; for (c=0 ; c<=cc ; c++) integrated [j] =integrated [j] + d [j+cr*w+c] ; for (c=0 ; c<w ; c++) col [c] =col [c] +d [j+cr*w+c] ; for (c=l ; c<=cc ; c++) integrated [j+c]=integrated [j+c-1]+col[c+cc] ; for (c= (cc+l) ; c< (w-cc) ; c++) integrated [j+c] =integrated [j+c-l] +col [c+cc]-col [c-cc-l] for (c= (w-cc) ; c<w ; c++) integrated [j+c]=integrated [j+c-1]-col[c-cc-1] ; for (r= (cr+l) ; r< (h-cr) ; r++) {j=r*w ; integrated [j] =integrated [j-w] ; for (c=0 ; c<=cc ; c++)

integrated [j] =integrated [j] + d [j+cr*w+c]- d [j-(cr+1)*w+c] ; for (c=0 ; c<w ; c++) col [c]=col[c]+d[j+cr*w+c] - d[j-(cr+1)*w+c] ; for (c=l ; c<=cc ; c++) integrated [j+c]=integrated[j+c-1]+col[c+cc] ; for (c= (cc+l) ; c< (w-cc) ; c++) integrated[j+c]=integrated[j+c-1]+col[c+cc]-col[c-cc-1] ; for(c=(w-cc) ; c<w c++) integrated [j+c]=integrated[j+c-1]-col[c-cc-1] ; for (r= (h-cr) ; r<h ; r++) j=r*w; integrated [j]=integrated[j-w] ; for (c=0 ; c<=cc ; c++) integrated[j]=integrated [j]-d j-(cr+1)*w+c] ; for (c=0 ; c<w ; c++) col [c] =col [c]-d [j-(cr+l) *w+c] ; for (c=l ; c<=cc ; c++)

integrated [j+c] =integrated [j+c-l] +col [c+cc] ; for (c= (cc+l) ; c< (w-cc) ; c++) integrated [j+c]=integrated[j+c-1)+col[c+cc]-col[c-cc-1] for (c= (w-cc) ; c<w ; c++) integrated [j+c]=integrated[j+c-1)-col[c-cc-1] ; /* /* for (r=0 ; r<h ; r++) for (c=0 ; c<w ; c++) {j=r*w ; if (integrated [j+c] ! =integrate_region rectangle-slow (ima ge, r, c, a, b)) printf ("%i %i %f\n", r, c, integrated [j+c]) ; } */ free (col) ; /* Now let's perform an area correction for boxes that are chopped by the edge of the image. */ area-max= ( (Integrated) wx) * ( (Integrated) wy) ;

a--; b- for (r=0 ; r<h ; r++) j=r*w; for (c=0 ; c<w ; c++) if ((r-b)<0) wy=r ; else wy=b ; if ( (r+b) > (h-l)) wy=wy+h-l-r ; else wy=wy+b ; wy++ ; if ((c-a) <0) wx=c ; else wx=a ; if ( (c+a) > (w-1)) wx=wx+w-1-c; else wx=wx+a ;

wx++ ; /* primer is only being used as a temporary variable here */ primer= (Integrated) (1. 0/ ( (double) wx)/ ( (double) wy)) ; /*primer=primer*primer*areamax ; */ integrated [j+c] =integrated [j+c] *primer ; /*printf ("of\n", integrated [j+c]) ; */ return (integrated) ; Integrated * integrate regions mask (unsigned short int *data, int w, int h, int width, double *mask) int row, col, sub-row, sub-col ; Integrated *integrated ; Integrated sum ; int region ; int pixel ;

int even, odd ; int mask point ; integrate, d= (Integrated *) malloc (sizeof (Integrated) *w*h) ; if (integrated==NULL) printf ("integrate regions : Failed to allocate memory for integration... \n") ; exit (0) ; for (pixel=0_ pixel<w*h ; pixel++) integrated [pixel] =0. 0 ; even = (int) ( (double) (width/2)- ( (double) width/2. 0) +1. 1) ; if (even==0) odd=l ; } else odd=0 ; } printf ("#width = i, even = %i, odd = 'ii\n", width, even, odd) ; for (row=width/2 ; row< (h-width/2+even) ; row++) f for (col=width/2 ; col< (w-width/2+even) ; col++)

region=row*w+col ; sum=0. 0 ; mask_point=0 ; for (sub_row=row-width/2 ; (subrow< (row+width/2+odd)) ; sub row++) for (sub col=col-width/2 ; (subcol< (col+width/2+odd)) ; sub col++) pixel = subrow*w+subcol ; /*if ( (sub_row<0) # (sub_col<) # (sub_row>=h) # (sub_col>=w) # (pixel>=w*h) ) printf ("#bad news in integrate %i %i %i\n", subrow, subcol, pixel) ; exit (l) ; } */ sum+= (Integrated) (mask [mask_point]* (double) data [pixel]) ; /*sum+= (Integrated) data [pixel] ; */ mask point++ ; integrated [region] =sum ; }

return (integrated) ; makefile # makefile for spot finding program # Definintions DOS to handle the slash character appropriately # MSVC for lack of getpagesize in Microsoft VC++ # WETDOT to choose mapintensityfunction for wet dot inspection #-funroll-loops-ffast-math-fforce-mem-fforce-addr -fstrength-reduce-fthread-jumps-fschedule-insns2 -malign-double-I/usr/include OBJS = tiff. o ppm. o read-Printer-info. o write tiff. o write_jpeg. o set parameters. o output-image. o integrate regions. o free-image. o sum images. o find boxes. o sort. o create-boxes. o background. o draw-boxes. o map_spots. o find angles. o output data. o mask. o multiimage. o statistics. o align images. o info. o find_array. o find-spots. o align background. o

read_parameters. o spot type. o filters. o overlap. o string_stuff. o CC = gcc RM = rm CFLAGSDEBUG, =-g3 CFLAGS =-Wall-02 IMAGEFLAGS =-Wall-02-s-static LINKS =/usr/lib/libtiff. a/usr/lib/libz. a /usr/lib/libjpeg. a-lm LINK = $ (CC) $ (CFLAGS) wspots : $ (OBJS) wspots. o defs. h structure. h makefile $ (LINK)-o wspots wspots. o $ (OBJS) $ (LINKS) wspots. o : wspots. c defs. h makefile structure. h $ (CC) $ (CFLAGS)-c wspots. c info. o : info. c defs. h makefile structure. h $ (CC) $ (CFLAGS)-c info. c string stuff. o : string stuff. c defs. h makefile $ (CC) $ (CFLAGS)-c string_stuff. c find array. o : find array. c defs. h makefile structure. h $ (CC) $ (CFLAGS)-c find array. c align_images. o : align-images. c defs. h makefile structure. h

$ (CC) $ (CFLAGS)-c align_images. c align background. o : align background. c defs. h makefile structure. h $ (CC), $ (CFLAGS)-c align background. c multi-image. o : multi-image. c defs. h makefile structure. h $ (CC). $ (CFLAGS)-c multi-image. c mask. o : mask. c defs. h makefile structure. h $ (CC) $ (CFLAGS)-c mask. c readprinterinfo. o : read-printer-info. c defs. h makefile structure. h $ (CC) $ (CFLAGS)-c readprinterinfo. c output data. o : output data. c defs. h makefile structure. h $ (CC) $ (CFLAGS)-c output_data. c output_image. o : output_image. c defs. h makefile structure. h $ (CC) $ (CFLAGS)-c output_image. c free-image. o : free-image. c defs. h makefile structure. h $ (CC) $ (CFLAGS)-c free-image. c

sum images. o : sum_images. c defs. h makefile structure. h $ (CC) $ (CFLAGS)-c sum_images. c tiff. o : tiff. c makefile $ (CC), $ (CFLAGS)-c tiff. c draw-boxes. o : draw boxes. c makefile $ (CC) $ (CFLAGS)-c draw-boxes. c find_boxes. o : find boxes. c makefile $ (CC) $ (CFLAGS)-c find_boxes. c map spots. o : map spots. c makefile structure. h defs. h $ (CC) $ (CFLAGS)-c map-spots. c create-boxes. o : create boxes. c makefile defs. h structure. h $ (CC) $ (CFLAGS)-c create-boxes. c remove overlapping boxes. o : removeoverlappingboxes. c makefile defs. h structure. h $ (CC) $ (CFLAGS)-c remove overlapping boxes. c quality. o : quality. c makefile defs. h structure. h $ (CC) $ (CFLAGS)-c quality. c write_tiff. o : write_tiff. c makefile defs. h structure. h $ (CC) $ (IMAGEFLAGS)-c write tiff. c

write_jpeg. o : write_jpeg. c makefile defs. h structure. h $ (CC) $ (IMAGEFLAGS)-c writejpeg. c background. o : background. c makefile defs. h structure. h $ (CC) $ (CFLAGS)-c background. c integrate_regions. o : integrate regions. c makefile $ (CC) $ (CFLAGS)-c integrate_regions. c ppm. o : ppm. c makefile $ (CC) $ (CFLAGS)-c ppm. c sort. o : sort. c makefile $ (CC) $ (CFLAGS)-c sort. c find_angles. o : find_angles. c makefile $ (CC) $ (CFLAGS)-c find_angles. c set-parameters. o : set parameters. c makefile defs. h structure. h $ (CC) $ (CFLAGS)-c set parameters. c read parameters. o : read_parameters. c makefile defs. h structure. h $ (CC) $ (CFLAGS)-c read_parameters. c statistics. o : statistics. c makefile defs. h structure. h $ (CC) $ (CFLAGS)-c statistics. c

find spots. o : find-spots. c makefile defs. h structure. h $ (CC) $ (CFLAGS)-c find spots. c spot type. o : spot type. c makefile defs. h structure. h $ (CC) $ (CFLAGS)-c spot type. c filters. o : filters. c makefile defs. h structure. h $ (CC) $ (CFLAGS)-c filters. c overlap. o : overlap. c makefile defs. h structure. h $ (CC) $ (CFLAGS)-c overlap. c clean : $ (RM) $ (OBJS) wspots wspots. o map-spots. c #include"defs. h" &num ifdef WET DOT double mapintensityfunction (struct box *b) {return (b [0]. spot. average-b [0]. background. average) ; &num else double map_intensity_function (struct box *b)

{double temp ; temp=b [0]. spot. average-b [0]. background. average ; if (temp<0. 0) temp=0. 0 ; return (b [0]. spot. area*b [0]. spot. area*temp) ; #endif int get-spot number (int pr, int pc, int sr, int sc, struct printer *p) {return (sc + p [0]. spots_per_row * (sr + p [0]. sports_per_column* (pc + p [0]. pinsperrow*pr))) ; void get xyfromspotandpin (double hp, double kp, double hs, double ks, struct printer *p, double *x, double *y)

{int pn ; /* Square grid */ if (p [0]. hexagonal==0) {if ((p[0].axp==NULL) # (p[0].ayp==NULL)<BR> (p[0].bxp=NULL) # (p[0].byp==NULL)) {x [0] =hp*p [0]. cx + kp*p [0]. dx + hs*p [0]. ax + ks*p [0]. bx ; y [0] =hp*p [0]. cy + kp*p [0]. dy + hs*p [0]. ay + ks*p [0]. by ; else {pn= ( (int) (p [0]. pinsperrow*kp + hp + 0. 5)) ; x [0] =hp*p [0]. cx + kp*p [0]. dx + hs*p [0]. axp [pn] + ks*p [0]. bxp [pn] ; y [0] =hp*p [0]. cy + kp*p [0]. dy + hs*p [0]. ayp [pn] + ks*p [0]. byp [pn] ; /* Hexagonal type 1 */ if (p [0]. hexagonal==1) if ((p[0]. axp==NULL) # (p[0].ayp==NULL) (p [0 bxp==NULL) ii (p [0]. byp==NULL)) {x [0] =hp*p [0]. cx + kp*p [0]. dx + hs*p [0]. ax + ks*p [0]. bx- (double) ( (int) ( (ks+0. 5)/2. 0)) * p [0]. ax ;

y [0] =hp*p [0]. cy + kp*p [0]. dy + hs*p [0]. ay + ks*p [0]. by- (double) ((int) ((ks+0.5)/2. 0)) * p [0]. ay ; else {pn= (, (int) (p [0]. pinsperrow*kp + hp + 0. 5)) ; x [0] =hp*p [0]. cx + kp*p [0]. dx + hs*p [0]. axp [pn] + ks*p [0]. bxp [pn]- (double) ( (int) ( (ks+0. 5)/2. 0)) * p [0]. axp [pn] ; y [0] =hp*p [0]. cy + kp*p [0]. dy + hs*p [0]. ayp [pn] + ks*p [0]. byp [pn]- (double) ( (int) ( (ks+0. 5)/2. 0)) * p [0]. ayp [pn] ; } /* Hexagonal type 2 */ if (p [0]. hexagonal==2) if((p[0].axp==NULL) (p[0].axp==NULL) (p [0]. bxp==NULL) # (p [0]. byp==NULL)) {x [0] =hp*p [0]. cx + kp*p [0]. dx + hs*p [0]. ax + ks*p [0]. bx- (double) ( (int) ( (ks+1. 5)/2. 0)) * p [0]. ax ; y [0] =hp*p [0]. cy + kp*p [0]. dy + hs*p [0]. ay + ks*p [0]. by- (double) (((int) ((ks+1.5)/2. 0)) * p [0]. ay ; else f pn= ( (int) (p [0]. pins_per_row*kp + hp + 0. 5)) ;

x [0] =hp*p [0]. cx + kp*p [0]. dx + hs*p [0]. axp [pn] + ks*p [0]. bxp [pn]- (double) ( (int) ( (ks+1. 5)/2. 0)) * p [0]. axp [pn] ; y [0] =hp*p [0]. cy + kp*p [0]. dy + hs*p [0]. ayp [pn] + ks*p [0]. byp, [pn]- (double) ( (int) ( (ks+1. 5)/2. 0)) * p [0]. ayp [pn] ; /* Hexagonal type 3 */ if (p [0]. hexagonal==3) if ((p[0]. axp==NULL) 11 (p [0]. ayp==NULL))) (p [0]. bxp==NULL) # # (p[0]. byp==NULL)) { x[0]=hp*p[0]. cx + kp*p [0]. dx + hs*p [0]. ax + ks*p [0]. bx- (double) ( (int) ( (hs+0. 5)/2. 0)) * p [0]. bx ; y [0]=hp*p[0]. cy + kp*p [0]. dy + hs*p [0]. ay + ks*p [0]. by- (double) ( (int) ( (hs+0. 5)/2. 0)) * p [0]. by ; else {pn= ( (int) (p [0]. pinsperrow*kp + hp + 0. 5)) ; x [0]=hp*p[0]. cx + kp*p [0]. dx + hs*p [0]. axp [pn] + ks*p [0]. bxp [pn]- (double) ( (int) ( (hs+0. 5)/2. 0)) * p [0]. bxp [pn] ; y [0] =hp*p [0]. cy + kp*p [0]. dy + hs*p [0]. ayp [pn] + ks*p [0]. byp [pn]- (double) ( (int) ( (hs+0. 5)/2. 0)) * p [0]. byp [pn] ;

/* Hexagonal type 4 */ if (p [0]. hexagonal==4) { if((p[0].axp==NULL) # (p[0].ayp==NULL) (p [0]. bxp==NULL)) j (p [0]. byp==NULL)) {x [0] =hp*p [0]. cx + kp*p [0]. dx + hs*p [0]. ax + ks*p [0]. bx- (double) ( (int) ( (hs+1. 5)/2. 0)) * p [0]. bx ; y [0] =hp*p [0]. cy + kp*p [0]. dy + hs*p [0]. ay + ks*p [0]. by- (double) ( (int) ( (hs+1. 5)/2. 0)) * p [0]. by ; else {pn= ( (int) (p [0]. pinsperrow*kp + hp + 0. 5)) ; x [0] =hp*p [0]. cx + kp*p [0]. dx + hs*p [0]. axp [pn] + ks*p [0]. bxp [pn]- (double) ( (int) ( (hs+1. 5)/2. 0)) * p [0]. bxp [pn] ; y [0] =hp*p [0]. cy + kp*p [0]. dy + hs*p[0].ayp[pn] + ks*p [0]. byp [pn]- (double) ( (int) ( (hs+1. 5)/2. 0)) * p [0]. byp [pn] ; void get_xyfromspotnumber (int n, struct printer *p, double *x, double *y)

{int hp, kp, hs, ks, ql, q2 ; <BR> <BR> kp=n/ (p [0]. pinsperrow*p [0]. spotsperrow*p [0]. spotsp er_colum) ; ql=n"-. (p [0]. pinsperrow*p [0]. spotsperrow*p [0]. spotsp er column) ; hp=ql/ (p [0]. spotsperrow*p [0]. spotspercolumn) ; q2=ql% (p [0]. spotsperrow*p [0]. spotspercolumn) ; ks=q2/p [0]. spots_per_row ; hs=q2p [0]. spotsperrow ; get_xyfromspotandpin(((double) hp), ( (double) kp), ( (double) hs), ( (double) ks), p, x, y) ; } void get_spotandpinfromnumber (int n, struct printer *p, int *pr, int *pc, int *sr, int *sc) {int ql, q2 ;

pr [0]=n/(p[0].pins_per_row*p[0].sports_per_row*p[0]. spot s per column) ; ql =n% (p [0]. pinsperrow*p [0]. spotsperrow*p [0]. spotsper column) ; pc [0] =ql/ (p [0]. spotsperrow*p [0]. spotspercolumn) ; q2 =q1%. (p [0]. spotsperrow*p [0]. spotspercolumn) ; sr [0] =q2/p [0].sports_per_row ; sc [0] =q2%p [0]. spotsperrow ; } int get_pin_number_from_spot_number (int n, struct printer *p) {int pr, pc, ql ; <BR> <BR> pr=n/ (p [0]. pinsperrow*p [0]. spotsperrow*p [0]. spotsp er column) ; <BR> <BR> ql=n (p [0]. pinsperrow*p [0]. spotsperrow*p [0]. spotsp er column) ; pc=ql/ (p [0]. spotsperrow*p [0]. spotspercolumn) ; return (pr*p [0]. pins_per_row+pc) ;

int get_rgb (int *r, int *g, int *b, int v, , int max) {double third, maxd, vd ; maxd= ((double) max) ; third=maxd/3. 0 ; vd= ( (double) v) ; /* RG mix */ if (third) b [0] =MAX-INTENSITY ; r [0] = (int) (3*vd) ; g [0] =max-r [0] ; /* BR mix */ if ( (vd>=third) && (vd< (2*third))) g [0] =MAX_INTENSITY ; b [0] = (int) (maxd* (vd-1. 0*third)/third) ; r[0]=max-b[0] ;

/* GB mix */ if (vd>=2*third) {r [0] =MAXINTENSITY ; g [0] = (int) (maxd* (vd-2. 0*third)/third) ; b [0]=max-g[0] ; return (0). ; void writemapppm (char *fname, int w, int h, int *s) {int i, n, max, r, g. b ; FILE *f ; f=fopen (fname,"w") ; if (f==NULL)

{printf ("Failed to open %s in write_map_ppm... \n", fname) ; return ; n=w*h ; max=0 ; for (i=0 ; i<n ; i++) if (s [i] >=max) max=s [i] ; fprintf (f, "P3\n# CREATOR : T\n%i %i\n%i\n", w, h, max) ; for (i=0 ; i<n ; i++) if (s [i] >=0) {getrgb (&r, &g, &b, s [i], max) ; fprintf (f, "%i %i %i ", r, g, b) ; else fprintf (f,"0 0 0") ; fprintf (f,"\n") ; fclose (f) ; void createmapimage (struct map_image *mi, struct map_spots_params *m, struct printer *p)

{double x, y ; int xi, yi, pr, pc, sn, sr, sc, <BR> <BR> <BR> <BR> <BR> r-ul,<BR> <BR> <BR> <BR> <BR> <BR> r-ur, rll, r_lr, cul, cur, c 11, clr, min row, min col, max-row, max_col, rs, re, cs, ce, r, c, z=0,

i, n, numspots, num_sports_per_grid, num_p, ins, xaxis, y_axis, center, c-center ; get_xyfromspotandpin(0.0, 0. 0,-0. 5,-0. 5, p, &x, &y) ; yi= ( (int) y) ; xi= ( (int) x) ; minrow=yi ; mincol=xi ; maxrow=yi ; maxcol=xi ; mi [0]. halfcolumn=-xi ; mi [0]. halfrow=-yi ; for (pr=0 ; pr<p [0]. pins_per_column ; pr++) for(pc=0 ; pc<p [0]. pins_per_row ; pc++) for (sr=0 ; sr<p [0]. sports_per_column ; sr++) for (sc=0 ; sc<p [0]. sports_per_row ; sc++) {if (p [0]. hexagonal==0) {

get_xyfromspotandpin(((double) pc), ( (double) pr), ( (double) sc)-0. 5, ((double) sr)-0. 5, p, &x, &y); yi= ( (int) y) ; xi= ( (int) x) ; if (yi<minrow) minrow=yi ; if (xi<mincol) mincol=xi ; if (yi>max row) maxrow=yi ; if (xi>max_col) max_col=xi ; get_xyfromspotandpin(((double) pc), ( (double) pr), ( (double) sc) +0. 5, ( (double) sr)-0. 5, p, &x, &y) ; yi= ( (int) y) ; xi= ( (int) x) ; if (yi<minrow) minrow=yi ; if (xi<mincol) mincol=xi ; if (yi>maxrow) maxrow=yi ; if (xi>maxcol) max_col=xi ; get_xyfromspotandpin(((double) pc), ( (double) pr), ((double) sc)-0. 5, ( (double) sr) +0. 5, p, &x, &y) ; yi= ( (int) y) ; xi= ( (int) x) ;

if (yi<minrow) minrow=yi ; if (xi<mincol) mincol=xi ; if (yi>maxrow) maxrow=yi ; if (xi>maxcol) max_col=xi ; get_xyfromspotandpin(((double) pc), ( (double) pr), ( (double) sc) +0. 5, ( (double) sr) +0. 5, p, &x, &y) ; yi= ( (int) y) ; xi= ( (int) x) ; if (yi<min_row) min_row=yi ; if (xi<min_col) min_col=xi ; if (yi>max_row) max_row=yi ; if (xi>max_col) max_col=xi ; else { get_xyfromspotandpin(((double) pc), ( (double) pr), ((double) sc)-1. 0, ( (double) sr), p, &x, &y) ; yi= ( (int) y) ;

xi= ( (int) x) ; if (yi<min_row) min_row=yi ; if (xi<mincol) mincol=xi ; if (yi>maxrow) maxrow=yi ; if (xi>maxcol) maxcol=xi ; get_xyfromspotandpin(((double) pc), ( (double) pr), ( (double) sc) +1. 0, ( (double) sr)-0. 5, p, &x, &y) ; yi= ( (int) y) ; xi= ( (int) x) ; if (yi<min_row) minrow=yi ; if (xi<mincol) mincol=xi ; if (yi>max_row) maxrow=yi ; if (xi>maxcol) max_col=ci ; get_xyfromspotandipin(((double) pc), ( (double) pr), ( (double) sc), ( (double) sr) +1. 0, p, &x, &y) ; yi= ( (int) y) ; xi= ( (int) x) ; if (yi<min_row) min_row=yi ; if (xi<min_col)

mincol=xi ; if (yi>maxrow) maxrow=yi ; if (xi>maxcol) maxcol=xi ; get_xyfromspotandpin(((double) pc), ( (double) pr), ( (double) sc) +0. 5, ((double) sr)-1. 0, p, &x, &y) ; yi= ( (int) y) ; xi= ( (int) x) ; if (yi<minrow) min_row=yi ; if (xi<min_col) min_col=xi ; if (yi>max_row) max_row=yi ; if (xi>max_col) max_col=xi ; if (m [0]. debug) printf ("min_row+%i max_row=%i\n", min_row, marrow) ; printf ("min_col=%i max_col=%i\n", min_col, max_col) ;

mi [0]. height=maxrow-minrow+l ; mi [0]. width =max_col-min-col+1 ; minrow=-minrow ; mincol=-mincol ; mi [0]. centerfirstspotrow=minrow ; mi [0]. centerfirstspotcolumn=mincol ; n=mi [0]. width*mi [0]. height ; mi [0]. image= (int *) malloc (n*sizeof (int)) ; if (mi [0]. image==NULL) {printf ("Failed to allocate mi [0]. image in create_map_image...\n") ; exit (-l) ; } /* let's fill the array with spot numbers */ for (i=0 ; i<n ; i++) mi [0]. image [i]=-1 ; for (pr=0 ; pr<p [0]. pins_per_column ; pr++) for (pc=0 ; pc<p [0]. pins_per_row; pc++) for (sr=0 ; sr<p [0]. sports_per_column ; sr++) for (sc=0 ; sc<p [0]. spots per row ; sc++) {sn=getspotnumber (pr, pc, sr, sc, p) ;

/* get the limits for the box */ if (p [0]. hexagonal==0) /* upper left */ get_xyfromspotandpin(((double) pc), ( (double) pr), ( (double) sc)-0. 5, ( (double) sr)-0. 5, p, &x, &y) ; r_ul=((int) y) ; c. ul= ( (int) x) ; rs=rul ; cs=cul ; re=rul ; ce=cul ; /* lower right */ get_xyfromspotandpin ( ( (double) pc), ( (double) pr), ( (double) sc) +0. 5, ( (double) sr) +0. 5, p, &x, &y) ; rlr= ( (int) y) ; c_lr= ( (int) x) ; if (r-lr<rs) rs=r_lr ; if (c_lr<cs) cs=c_lr ; if (rlr>re) re=rlr ; if (clr>ce) ce=clr ; /* lower left */

get_xyfromspotandpin (((double) pc), ( (double) pr), ( (double) sc)-0. 5, ( (double) sr) +0. 5, p, &x, &y) ; rill= ( (int) y) ; c-ll= ( (int) x) ; if (rll<rs) rs=r_11 ; if (c_11<cs) cs=c_11 ; if (r_11>re) re=r_11 ; if (c_11>ce) ce=c_ll ; /* upper right */ get_xyfromspotandpin (((double) pc), ( (double) pr), ( (double) sc) +0. 5, ((double) sr)-0. 5, p, &x, &y) ; r_ur=((int) y) ; c_ur=((int) x) ; if (rur<rs) rs=rur ; if (cur<cs) cs=cur ; if (rur>re) re=rur ; if (cur>ce) ce=cur ; /* printf ("r_ul=%i r_ur=%i r_ll=%i r_lr=%i\n", rul, rur, rll, rlr) ; printf ("c_ul=%i c_ur=%i c_ll=%i c_lr=%i\n", cul, cur, cll, clr) ;

printf ("rs=%i i re=*-. cs=%i ce=%i sn=%i\n", rs, re, cs, ce, sn) ; */ for (r=rs ; r<re ; r++) for (c=cs ; c<ce ; c++) if (r>= ((c-c ul) * (r ur-r ul)/ (c ur-c ul) +r ul)) if (r<= ( (c-cul) * (r_lr-r_ll)/(c_lr-c_ll)+r_ll)) if (c>= ((r-r ul) * (cll-cul)/ (rll-rul) +cul)) { if (c<= ((r-r_ur) * (c_lr-c_ur)/(r_lr-r_ur)+c_ur)) {if(((r+min_row)<mi[0]. height) && ( (c+mincol) <mi [0]. width) && ((r+min_row) > (-1)) && ((c+min_col) > (-1))) {z= (r+minrow) *mi [0]. width+c+mincol ; mi [0]. image [z] =sn ; else if (m [0]. debug) printf ("pr=%i pc=%i sr=%i sc=%i r=%i c=%i sn=%i z=%i\n", pr, pc, sr, sc, r+minrow, c+mincol, sn, z) ;

} } } else /* dead center */ get_xyfromspotandpin(((double) pc), ( (double) pr), ( (double) sc), ( (double) sr), p, &x, &y) ; r_center=((int) y) ; c_center=((int) x) ; get_xyfromspotandpin(((double) pc), ((double) pr), ( (double) sc) +0. 5, ( (double) sr), p, &x, &y) ; xaxis= (int) fabs (x-((double) c-center)) ; get_xyfromspotandpin(((double) pc), ( (double) pr), ( (double) sc), ( (double) sr) +0. 5, p, &x, &y) ; y_axis= (int) fabs (y- ((double) r_center)) ; rs=r center-yaxis ; re=r_center+y axis+l ; cs=c center-xaxis ; ce=ccenter+xaxis+l ; for (r=rs ; r<re ; r++) for (c=cs ; c<ce ; c++) if (((r+min_row) <mi [0]. height) && ((c+min_col) <mi [0]. width) &&

((r+min_row) > (-1)) && ((c+min_col) > (-1))) {if((((double) (r-r, center) * (r-rcenter))/ (yaxis*yaxis) + ( (double) (c-c_center) * (c-c_center))/(x_axis*x_axis)) <1. 0) {z= (r+minrow) *mi [0]. width+c+mincol ; mi [0]. image [z] =sn ; else {if (m [0]. debug) printf ("pr=%i pc=%i sr=%i sc=%i r=%i c=%i sn=%i z=%i\n', pr, pc, sr, sc, r+minrow, c+mincol, sn, z) ; } } num_pins=p[0].pins_per_row*p[0].pins_per_column ; num_spots_per_grid=p[0].sports_per_row*p[0].sports_per_co lumn ; num_spots=num_pins*num_spots_per_grid; mi [0]. number= (int *) malloc (numpins*sizeof (int)) ; if (mi [0]. number==NULL)

{printf ("Failed malloc for mi [0]. number in create map-image... \n") ; exit (-l) ; mi [0]. distance= (double *) malloc (numpins*sizeof (double)) ; if (mi [0]. distance==NULL) {printf ("Failed malloc for mi [0]. distance in create_map_image...\n") ; exit (-l) ; mi [0]. intensity= (double *) malloc (numpins*sizeof (double)) ; if (mi [0]. intensity==NULL) {printf ("Failed malloc for mi [0]. intensity in create_map_image...\n") ; exit (-l) ; } mi [0]. occupied_distance= (double *) malloc (numspots*sizeof (double)) ; if (mi [0]. occupieddistance==NULL) {printf ("Failed malloc for mi [0]. occupied_distance in create map image... \n") ; exit (-l) ;

mi [0]. occupied= (int *) malloc (numspots*sizeof (int)) ; if (mi [0]. occupied==NULL) {printf ("Failed malloc for mi [0]. occupied in create_map_image... \n") ; exit (-l) ; mi [0]. row offset= (int *) malloc (num_pins*sizeof (int)) ; if (mi [0]. rowoffset==NULL) {printf ("Failed malloc for mi [0]. row offset in createmapimage... \n") ; exit (-l) ; mi [0]. col offset= (int *) malloc (numpins*sizeof (int)) ; if (mi [0]. col_offset==NULL) {printf ("Failed malloc for mi [0]. col-offset in create map-image... \n") ; exit (-l) ; for (i=0 ; i<numpins ; i++) {mi [0]. number [i] =0 ; mi [0]. intensity [i] =0. 0 ; mi [0]. distance [i] =DBLMAX ; mi [0]. row_offset[i]=p[0].origin_row ;

mi [0]. col_offset[i]=p[0].origin_column ; } /* get_internal_width_and_height should be called after mapimageremovemissing*/ void getinternalwidthandheight (struct map_image *mi) int r, c, max_row, min row, max_col, min col, j ; minrow=mi->height ; maxrow=-l ; max col=-1 ; mincol=mi->width ; for (r=0 ; r<mi->height ; r++) j=r*mi->width ; for (c=0 ; c<mi->width ; c++)

{if (mi->image [j+c] > (-1)) {if (r>maxrow) maxrow=r ; if (r<minrow) minrow=r ; if (c>max col) maxcol=c ; if (c<mincol) mincol=c ; mi->internalwidth=maxcol-mincol+l ; mi->internal_height=max_row-min_row+1 ; /* if (mi->debug==l) printf ("internal_width=%i internal_height=%i width=%i height=%i min_row=%i min_col=%i max_row=%i max_col=%i\n", mi->internalwidth, mi->internalheight, mi->width, mi->height, min_row, min_col, max_row, max_col) ; */ void map-image remove missing (struct map_image *mi, struct printer *p) { double x, y ; int sn, r, c, z, rul, cul, rlr, clr, rll, cll, rur, cur, rs, cs, re, ce, pr, pc, sr, sc ; for (pr=0 ; pr<p [0]. pinspercolumn ; pr++)

for (pc=0 ; pc<p [0]. pins_per_row ; pc++) for (sr=0 ; sr<p [0]. spots_per_column ; sr++) for (sc=0 ; sc<p [0]. spotsperrow ; sc++) { sn=get_spot_number (pr, pc, sr, sc, p) ; if ((p[0].spot_type[sn]==NEGATIVE) (p [0]. spot_type[sn]==MISSING) (p [0]. spot_type[sn]==EMPTY)) {get_xyfromspotandpin (((double) pc), ((double) pr), ((double) sc) -0.5, ((double) sr)-0. 5, p, &x, &y) ; r_ul=((int) y) ; c_ul=((int) x) ; rs=rul ; cs=cul ; re=rul ; ce=cul ; /* lower right */ get_xyfromspotandpin(((double) pc), ((double) pr), ( (double) sc) +0. 5, ( (double) sr) +0. 5, p, &x, &y) ; r_lr= ((int) y) ; clr= ( (int) x) ;

if (rlr<rs) rs=rlr ; if (clr<cs) cs=clr ; if (rlr>re) re=rlr ; if (clr>ce) ce=clr ; /* lower left */ get_xyfromspotandpin (((double) pc), ( (double) pr), ( (double) sc)-0. 5, ( (double) sr) +0. 5, p, &x, &y) ; r-ll= ( (int) y) ; c_ll=((int) x) ; if (r_ll<rs) rs=r_ll ; if (c_ll<cs) cs=c_ll ; if (r_ll>re) re=r_ll ; if (c_ll>ce) ce=c_ll ; /* upper right */ get_xyfromspotandpin (((double) pc), ( (double) pr), ( (double) sc) +0. 5, ( (double) sr)-0. 5, p, &x, &y) ; r_ur=((int) y) ; c_ur=((int) x) ; if (rur<rs) rs=rur ; if (cur<cs) cs=cur ;

if (rur>re) re=rur ; if (cur>ce) ce=cur ; for (r=rs ; r<re ; r++) for (c=cs ; c<ce ; c++) z= (r+mi [0]. center_first_sport_row) *mi [0]. width + c+mi [0]. center-first spot column ; _ if (mi [0]. image [z] ==sn) mi [0]. image [z]=-1 ; } } int get_spot_number_from_map_image (struct map image *mi, struct box *b, int row_offset, int col_offset) int map_image_row, map_image_col ; map_image_row=b[0].box_row -rowoffset+mi [0]. centerfirstspot row ;

map_image_col=b [0]. box_colum-col_offset+mi[0].center_first_ if ((map_image_row> (-l)) && (map_image_row<mi [0]. height) && (map_image_col>(-1)) && (map_image_col<mi [0]. width)) return (mi [0.]. image [map_image_row*mi[0].width+map_image_ col]) ; else return (-l) ; } void map-coarse (struct image data *our-image, struct map-image *mi, struct printer *p, int inc, int debug) {int r, <BR> <BR> <BR> <BR> done-r,<BR> <BR> <BR> <BR> <BR> <BR> c,<BR> <BR> <BR> <BR> <BR> done c, re, ce, number, i,

sn, num_spots, <BR> <BR> <BR> <BR> numspotspergrid,<BR> <BR> <BR> <BR> <BR> <BR> numpins, num boxes ; double intensity, distance, y, d ; struct box *b ; b=our_image[0].boxes ; numboxes=ourimage [0]. numboxes ; num_pins=p[0].pins_per_row*p[0].pins_per-column ; num_spots_per_grid=p[0].spots_per_row*p[0].spots_per_co lumn ; num_spots=num_pins*num_spots_per_grid ; ce=our-image [0]. width- (mi [0]. internalwidth 2*mi [0]. half_column) ; re=our-image [0]. height- (mi [0]. internalheight- 2*mi [0]. half-row) ;

if (inc<l) inc=l ; for (r=0, done r=0 ; done r==0 ; r=r+inc) if (r>=re) r=re-1 ; done_r=1 ; for (c=0, done_c=0 ; done_c==0 ; c=c+inc) if (c>=ce) c=ce-1 ; done_c=1 ; for (i=o ; i<numspots ; i++) mi [0]. occupied [i] =-1 ; number=0 ; intensity=0. 0 ; distance=0. 0 ; for (i=0 ; i<numboxes ; i++) sn=get_spot_number_from_map_image (mi, &b [i], r, c) ; if (sn ! = (-l)) get_xyfromspotnumber (sn, p, &x, &y) ; d=sqrt ( ( ( (double) b [i]. box_row -r)-y) * ( ( (double) b [i]. boxrow-r)-y) +

( ( (double) b [i]. boxcolumn-c)-x) * ( ( (double) b [i]. box column-c)-x)) ; if (mi [0]. occupied [sn] == (-1)) {number++ ; intensity=intensity+map_intensity_function (&b [i]) ; distance=distance+d ; mi [0]. occupied [sn] =i ; mi [0]. occupied_distance [sn] =d ; else if ((mi[0]. occupied [sn]>(-1)) && (d<mi[0].occupied_distance[sn])) {<BR> intensity=intensity+map_intensity_function (&b [i]) -map-intensity-function (&b [mi [0]. occupied [sn]]) ; distance=distance+d-mi [0]. occupied_distance [sn] ; mi [0]. occupied [sn] =i ; mi [0]. occupied distance [sn] =d ; } if ((intensity >mi [0]. intensity [0]) ||

((intensity==mi[0]. intensity [0]) && (distance<mi [0]. distance [0]))) {mi [0]. number [0]=number ; mi [0]. intensity [0] =intensity ; mi [0]. distance [0] =distance ; mi [0]. row_offset[0]=r ; mi [0]. col_offset[0]=c ; if (debug) printf ("r=%5i c=o5i number=o6i distance=o+e intensity=%+e\n", r, c, number, distance, intensity) ; } for (i=l ; i<numpins ; i++) {mi [0]. row_offset[i]=mi[0].row_offset[0] ; mi [0]. col_offset[i]=mi[0].col_offset[0] ; } void map-fine (struct image_data *our_image, struct map image *mi, struct printer *p, int inc, int range_row, int range column,

int debug) {int r, c, re, ce, rs, cs, rf, cf, number, i, sn, num-spots, numspotspergrid, num_pins, numboxes ; double intensity, distance, <BR> <BR> <BR> <BR> x,<BR> <BR> <BR> <BR> Y, d ; struct box *b ; b=our-image [0]. boxes ; num_boxes=our_image[0].num_boxes ;

num_pins=p [0]. pinsperrow*p [0]. pinspercolumn ; <BR> <BR> numspotspergrid=p [0]. spotsperrow*p [0]. spotsperco lumn ; num_spots=num_pins*num_spots_per_grid ; ce=our_image [0]. width- (mi [0]. internalwidth 2*mi [0]. half_column) ; re=our_image [0]. height-(mi[0].internal_height - 2*mi [0]. half-row) ; if (inc<1) inc=l ; rs=mi [0]. rowoffset [0]-rangerow ; if (rs<0) rs=0 ; rf=mi[0].row_offset[0]+range_row ; if (rf>re) rf=re ; cs=mi [0]. coloffset [0]-rangecolumn ; if (cs<0) cs=O ; cf=mi [0]. col_offset[0]+range_column ; if (cf>ce) cf=ce ; for (r=rs ; r<rf ; r=r+inc)

for (c=cs ; c<cf ; c=c+inc) {for (i=0 ; i<numspots ; i++) mi [0]. occupied [i] =-1 ; number=0 ; intensity=0. 0 ; distance=0. 0 ; for (i=0 ; i<numboxes ; i++) {sn=getspotnumberfrommapimage (mi, &b [i], r, c) ; if (sn ! = (-l)) {getxyfromspotnumber (sn, p, &x, &y) ; d=sqrt ( ( ( (double) b [i]. boxrow-r)-y) * ( ( (double) b [i]. boxrow-r)-y) + ( ( (double) b [i]. boxcolumn-c)-x) * ( ( (double) b [i]. boxcolumn-c)-x)) ; if (mi [0]. occupied [sn] == (-1)) {number++ ; intensity=intensity+map_intensity_function (&b [i]) ; distance=distance+d ; mi [0]. occupied [sn] =i ; mi [0]. occupied_distance [sn] =d ; else

if ((mi [0]. occupied [sn] >(-1)) && (d<mi [0]. occupieddistance [sn])) intensity=intensity+map_intensity_function (&b [i])-map_i ntensity_function (&b [mi [0]. occupied [sn]]) ; distance=distance+d-mi [0]. occupied_distance [sn] ; mi [0]. occupied [sn] =i ; mi [0]. occupied_distance [sn] =d ; if ((intensity >mi [0]. intensity [0]) t t ((intensity==mi[0]. intensity [0]) && (distance<mi [0]. distance [0]))) {mi [0]. number [0] =number ; mi [0]. intensity [0] =intensity ; mi [0]. distance [0] =distance ; mi [0]. row_offset[0]=r; mi [0]. col_offset[0]=c ; if (debug) printf ("r=%5i c=W5i number=o6i distance=o+e intensity=%+e\n", r, c, number, distance, intensity) ;

for (i=1 ; i<num_pins ; i++) {mi [0]. row_offset[i]=mi[0].row_offset[0] ; mi [0]. col_offset[i]=mi[0].col_offset [0] ; void map_pin_by_pin (struct image data *our-image, struct map-image *mi, struct printer *p, int inc, int range-row, int range column, int debug) {int r, re, ce, rs, cs, rf, cf, *number, i, sn, *row-offset, *col_offset, numspots,

numspotspergrid, num_pins, num boxes, pn ; double *intensity, *distance, y, d ; struct box *b ; b=ourimage [0]. boxes ; numboxes=ourimage [0]. numboxes ; num_pins=p[0].pins_per_row*p[0].pins_per_column ; num_spotsper_grid=p[0].spots_per_row*p[0].spots_per_co lumn ; num_spots=num_pins*num_spots_per_grid ; ce=our_image[0].width -(mi[0].internal_width - 2*mi [0]. half_column) ; re=our-image [0]. height-(mi[0].internal_height - 2*mi [0]. half-row) ; row_offset= (int *) malloc (sizeof (int) *numpins) ; if (rowoffset==NULL)

{printf ("Failed malloc for row-offset in map_in_by_pin... \n") ; exit (-l) ; col offset= (int *) malloc (sizeof (int) *numpins) ; if (coloffset==NULL) {printf ("Failed malloc for col-offset in map_pin_by_pin... \n") ; exit (-l) ; number= (int *) malloc (sizeof (int) *numpins) ; if (number==NULL) {printf ("Failed malloc for number in map_pin_by_pin... \n") ; exit (-l) ; distance= (double *) malloc (sizeof (double) *num_pins) ; if (distance==NULL) {printf ("Failed malloc for distance in map_pin_by_pin... \n") ; exit (-l) ; } intensity= (double *) malloc (sizeof (double) *numpins) ; if (intensity==NULL)

{printf ("Failed malloc for intensity in map_pin_by_pin... \n") ; exit (-l) ; for (i=0 ; i<numpins ; i++) {mi [0]. intensity [i] =0. 0 ; mi [0]. distance [i] =0. 0 ; mi [0]. number [i] =0 ; row_offset[i]=mi[0].row_offset [i] ; col_offset[i]=mi[0].col_offset[i] ; } for (i=0 ; i<numspots ; i++) mi [0]. occupied [i3=-1 ; for (i=0 ; i<numboxes ; i++) { sn=get_spot_number_from_map_image (mi, &b [i], mi [0]. rowoffset [0], mi [0]. coloffset [0]) ; if (sn ! = (-l)) {pn=getpinnumberfromspotnumber (sn, p) ; get_xyfromspotnumber (sn, p, &x, &y) ; d=sqrt ( ( ( (double) b [i]. box-row -mi [0]. rowoffset [pn])-y) * (((double) b [i]. box-row -mi [0]. rowoffset [pn])-y) + ( ( (double) b [i]. box-column-mi [0]. coloffset [pn])-x) *

( ( (double) b [i]. boxcolumn-mi [0]. coloffset [pn])-x)) ; if (mi [0]. occupied [sn] == (-1)) {mi [0]. number [pn] ++ ; mi [0]. intensity [pn] =mi [0]. intensity [pn] +map_intensity_f unction (&b [i]) ; mi [0]. distance [pn]=mi[0]. distance [pn] +d ; mi [0]. occupied [sn] =i ; mi [0]. occupied_distance[sn]=d ; else if ((mi[0]. occupied [sn] > (-1)) && (d<mi [0]. occupieddistance [sn])) mi [0]. intensity [pn] =mi[0]. intensity [pn] +mapintensityf unction (&b [i]) -map_intensity_function (&b [mi [0]. occupied [sn]]) ; mi [0]. distance [pn]=mi[0]. distance [pn] +d-mi [0]. occupied_ distance [sn] ; mi [0]. occupied [sn] =i ; mi [0]. occupied_distance[sn]=d ;

for (pn=0 ; pn<num_pins ; pn++) if (debug) printf (pin='-. number distance=% +e intensity=%+e\n", pn, mi [0]. number [pn], mi [0]. distance [pn], mi [0]. intensity [pn]) ; /* Pin by pin */ if (inc<l) inc=l ; rs=-((int) range_row0 ; cs=- ( (int) range-column) ; rf= ((int) range_row) ; cf= ((int) range_column); for (r=rs ; r<rf ; r=r+inc) for (c=cs ; c<cf ; c=c+inc) {for (pn=0 ; pn<num_pins ; pn++) {for (i=0 ; i<num-spots ; i++) mi [0]. occupied [i] =-1 ; number [pn] =0 ; distance [pn] =0. 0 ; intensity [pn] =0. 0 ;

for (i=0 ; i<numboxes ; i++) {sn=getspotnumberfrommapimage (mi, &b [i], row_offset[pn]+r, col_offset[pn]+c) ; if (sn ! = (-l)) if (pn==getpinnumberfromspotnumber (sn, P)) {get_xyfromspotnumber (sn, p, &x, &y) ; d=sqrt ( ( ( (double) b [i]. box-row - (row_offset[pn]+r)) -y) * ( ( (double) b [i]. box-row -(row_offset[pn]+r)) -y) + ( ( (double) b [i]. box_column- (col_offset[pn]+c)) -x) * ( ( (double) b [i]. box_column- (col_offset [pn]+c))-x)) ; if (mi [0]. occupied [sn] == (-1)) {number [pn] ++ ; intensity [pn] =intensity [pn] +mapintensityfunction (&b [i ]); distance [pn] =distance [pn] +d ; mi [0]. occupied [sn] =i ; mi [0]. occupied_distance [sn]=d ; } else if ((mi[0]. occupied [sn] > (-1)) && (d<mi [0]. occupieddistance [sn]))

intensity [pn] =intensity [pn] +mapintensityfunction (&b [i ))-map-intensity function (&b [mi [0]. occupied [sn]]) ; distance [pn] =distance [pn] +d-mi [0]. occupied distance [sn] ; mi [0]. occupied [sn] =i ; mi [0]. occupied_distance[sn]=d ; if (number [pn] ! =0) if ((intensity[pn] >mi[0]. intensity [pn]) ## ((intensity [pn] ==mi [0]. intensity [pn]) && (distance [pn] <mi [0]. distance [pn]))) {mi [0]. intensity [pn] =intensity [pn] ; mi [0]. number [pn] =number [pn] ; mi [0]. distance [pn] =distance [pn] ; mi [0]. row_offset [pn]=row_offset [pn] +r ; mi [0]. col_offset [pn]=col_offset [pn] +c ; if (debug) printf ("pin=%3i r=%5i c=%5i number=%5i distance=%+e intensity=%+e\n", pn, mi [0]. rowoffset [pn], mi [0]. coloffset [pn], mi [0]. number [pn], mi [0]. distance [pn], mi [0]. intensity [pn]) ;

} free (number) ; free (distance) ; free (intensity) ; free (row-offset) ; free (coloffset) ; void map_distance_minimization (struct image data *our-image, struct map_image *mi, struct printer *p, int inc, int range_row, int range column, int debug) {int r, c, re, ce, rs, cs, rf, cf, i,

sn, *row offset, *col_offset, num-spots, num_spots_per_grid, numjpins, num boxes, pn, *number, *s point ; double *distance, *intensity, <BR> <BR> <BR> <BR> <BR> x,<BR> <BR> <BR> <BR> <BR> Y, d ; struct box *b ; b=ourimage [0]. boxes ; numboxes=ourimage [0]. numboxes ; numpins=p [0]. pinsperrow*p [0]. pinspercolumn ; num_spots_per_grid=p [0] .spots_per_row*p[0] .spots_per_co lumn ; num_spots=num_pins*num_spots_per_grid ;

ce=our_image [0] .width - (mi [0] .internal_width - 2*mi [0]. half_column) ; re=our-image [0]. height- (mi [0]. internalheight- 2*mi [0]. half-row) ; row_offset= (int *) malloc (sizeof(int)*num_pins) ; if (rowoffset==NULL) {printf ("Failed malloc for row-offset in mapdistanceminimization... \n") ; exit (-l) ; col_ofset= (int *) malloc (sizeof (int) *numpins) ; if (coloffset==NULL) {printf ("Failed malloc for col-offset in map_distance_minimization...\n") ; exit (-l) ; distance= (double *) malloc (sizeof (double) *num_pins) ; if (distance==NULL) {printf ("Failed malloc for distance in map_distance_minimization...\n") \n") ; exit (-l) ; } intensity= (double *) malloc (sizeof (double) *num-pins) ; if (distance==NULL)

{printf ("Failed malloc for intensity in map_distance_minimization...\n") ; exit (-l) ; number= (int *) malloc (sizeof (int) *numpins) ; if (number==NULL) {printf ("Failed malloc for number in map_distance_minimization...\n") \n") ; exit (-1) ; for (i=0 ; i<numpins ; i++) {mi [0]. distance [i] =0. 0 ; mi [0]. number [i] =0 ; mi [0]. intensity [i] =0. 0 ; row_offset[i]=mi[0].row_offset [i] ; col_offset[i]=mi[0].col_offset [i] ; for (i=0 ; i<numspots ; i++) mi [0]. occupied [i] =-1 ; for (i=0 ; i<numboxes ; i++) b [i]. boxtype=NOTINGRID ; for (pn=0 ; pn<num_pins ; pn++) for (i=0 ; i<numboxes ; i++)

{ sn=get_spot_number_from_map_Image (mi, &b [i], row_offset[pn], col_offset [pn]) ; if (sn ! = (-l)) if (pn==getpinnumberfromspotnumber (sn, p)) {getxyfromspotnumber (sn, p, &x, &y) ; d=sqrt ( ( ( (double) b [i]. box-row -rowoffset [pn])-y) * ( ( (double) b [i]. box-row -row offset [pn])-y) + ( ( (double) b [i]. boxcolumn-coloffset [pn])-x) * ( ( (double) b [i]. boxcolumn-coloffset [pn])-x)) ; if (mi [0]. occupied [sn] == (-1)) b [i]. boxtype=INGRID ; mi [0]. number [pn] ++ ; mi [0]. intensity [pn] =mi [0]. intensity [pn] +mapintensityf unction (&b [i]) ; mi [0]. distance [pn] =mi [0]. distance [pn] +d ; mi [0]. occupied [sn] =i ; mi [0]. occupied_distance[sn]=d ; else if ((mi[0].occupied[sn] >(-1)) && (d<mi [0]. occupied distance [sn])) {b [i]. boxtype=INGRID ; b [mi [0]. occupied [sn]]. boxtype=NOTINGRID ;

mi [0]. intensity [pn] =mi [0]. intensity [pn] +map_intensity_f unction (&b [i])-map_intensity_function (&b [mi [0]. occupied [sn]]) ; mi [0]. distance [pn] =mi [0]. distance [pn] +d-mi [0]. occupied_ distance [sn] ; mi [0]. occupied_distance [sn]=d ; mi [0]. occupied [sn] =i ; /* Distance minimization on a pin by pin basis */ /* printf ("#Perform reverse list linkage and check intensity, distance, and numbers... \n") ; */ /* Set up an array of int's to store the grid position number where each good spot is located */ s point= (int *) malloc (sizeof (int) *nbboxes) ; for (i=0 ; i<numboxes ; i++) s_point [i] =-l ; for (sn=0 ; sn<numspots ; sn++) if (mi [0]. occupied [sn] > (-1))

if (b [mi [0]. occupied [sn]]. boxtype==INGRID) s point [mi [0]. occupied [sn]] =sn ; for (pn=0 ; pnnum_pins ; pn++) if (debug) printf (pin=*-. number distance=%+e intensity=%+e\n", pn, mi [0]. number [pn], mi [0]. distance [pn], mi [0]. intensity [pn]) ; if (inc<l) inc=l ; rs=-((int) range_row) ; cs=-((int) range_column); rf= ((int) range_row) ; cf= ((int) range_column); for (r=rs ; r<rf ; r=r+inc) for (c=cs ; c<cf ; c=c+inc) {for (pn=0 ; pn<num_pins ; pn++) {number [pn] =0 ; intensity [pn] =0. 0 ; distance [pn] =0. 0 ; for (i=0 ; i<numboxes ; i++) {if (b [i]. boxtype==INGRID)

{getxyfromspotnumber (spoint [i], p, &x, &y) ; pn=getpinnumberfromspotnumber (spoint [i], p) ; d=sqrt ( ( ( (double) b [i]. box-row -(row_offset [pn] +r))-y) * ( ( (double) b [i]. box-row -(row_offset[pn]+r))-y) + (((double) b [i]. box_column-(col_offset[pn]+c))-x) * ( ( (double) b [i]. box_column-(col_offset[pn]+c))-x)) ; distance [pn] =distance [pn] +d ; number [pn] ++ ; intensity[pn]=intensity[pn]+map_intensity_fusion(&b [i <BR> <BR> <BR> <BR> ) ;<BR> <BR> <BR> <BR> <BR> <BR> <BR> } for (pn=0 ; pn<num_pins ; pn++) if (distance [pn] <mi [0]. distance [pn]) {mi [0]. distance [pn]=distance[pn] ; mi [0]. intensity [pn]=intensity[pn] ; mi [0]. number [pn] =number [pn] ; mi [0]. row_offset[pn]=row_offset [pn] +r ; mi [0]. col_offset[pn]=col_offset[pn]+c ; if (debug)

printf ("pin=%3i r=%5i c=%5i number=%5i distance=%+e intensity=%+e\n", pn, mi [0]. row_offset[pn], mi [0]. coloffset [pn], mi [0]. number [pn], mi [0]. distance [pn], mi [0] intensity [pn]) ; free (row_offset) ; free (col offset) ; free (distance) ; free (number) ; free (intensity) ; free (s point) ; void map_assign (struct image_data *our_image, struct map-image *mi, struct printer *p, int debug, int snap_negatives) {int i, sn, pr, pc, sr, sc, num_spots,.

numspotspergrid, num_pins, numboxes, pn, *s-point ; double x, Y, d ; struct box *b ; b=our_image [0]. boxes ; numboxes=ourimage [0]. numboxes ; numpins=p [0]. pinsperrow*p [0]. pinspercolumn ; <BR> <BR> numspotspergrid=p [0]. spotsperrow*p [0]. spotsperco lumn ; num_spots=num_pins*num_spots_per_grid ; p [0]. row_offsets+ (int *) malloc (num_pins*sizeof (int)) ; if (p [0]. rowoffsets==NULL) {printf ("Failed malloc for p [0]. row-offsets in map_assign... \n") ; exit (-l) ;

p [0]. column offsets= (int *) malloc (numpins*sizeof (int)) ; if (p [0]. columnoffsets==NULL) {printf ("Failed malloc for p [0]. column-offsets in map_assign... \n") ; exit (-l) ; for (i=O ; # i<numpins ; i++) p [0]. row_offsets[i]=mi[0].row_offset [i] ; p [0]. column_offsets[i]=mi[0].col_offset [i] ; mi [0]. number [i] =0 ; mi [0]. intensity [i] =0. 0 ; mi [0]. distance[i]=0. 0 ; } for (i=0 ; i<numspots ; i++) mi [0]. occupied [i] =-1 ; for (i=0 ; i<numboxes ; i++) b [i]. boxtype=NOTINGRID ; for (pn=0 ; pn<num_pins ; pn++) for (i=0 ; i<numboxes ; i++) {sn=getspotnumberfrommapimage (mi, &b [i], mi [0]. rowoffset [pn], mi [0]. col_offset[pn]) ; if (sn ! = (-l)) if (pn==getpinnumberfromspotnumber (sn, p))

{get_xyfromspotnumber (sn, p, &x, &y) ; d=sqrt ( ( ( (double) b [i]. box-row -mi [0]. rowoffset [pn])-y) * ( ( (double) b [i]. box-row -mi [0]. row_offset[pn])-y) + ( ( (double) b [i]. boxcolumn-mi [0]. coloffset [pn])-x) * ( ( (double)' b [i]. box_column-mi[0].col_offset[pn])-x)) ; if (mi [0]. occupied [sn] == (-1)) {b b[i]. boxtype=INGRID ; mi [0]. number [pn] ++ ; mi [0]. intensity [pn] =mi [0]. intensity [pn] +mapintensityf unction (&b [i]) ; mi [0]. distance [pn] =mi [0]. distance [pn] +d ; mi [0]. occupied [sn] =i ; mi [0]. occupied_distance[sn]=d ; 'else if ((mi[0]. occupied [sn] > (-1)) && (d<mi [0]. occupied_distance[sn])) {b [i]. boxtype=INGRID ; mi [0]. intensity [pn]=mi[0]. intensity [pn] +map_intensity_f unction (&b[i])-map_intensity_function(&b[mi[0]. occupied [sn]]) ; mi [0]. distance [pn] =mi [0]. distance [pn]+d-mi[0].occupied distance [sn] ;

b [mi [0]. occupied [sn]]. boxtype=NOTINGRID ; mi [0]. occupied_distance[sn]=d ; mi [0]. occupied [sn] =i ; /* Set up an array of int's to store the grid position number where each good spot is located */ s point= (int *) malloc (sizeof (int) *nbboxes) ; for (i=0 ; i<num boxes ; i++) s_point [i] =-l ; for (sn=0 ; sn<num-spots ; sn++) if (mi [0]. occupied [sn] > (-1)) if (b [mi [0]. occupied [sn]]. box_type==IN_GRID) s_point [mi [0]. occupied [sn]] =sn ; for (i=0 ; i<numboxes ; i++) if (b [i]. boxtype==INGRID) {get_spotandpinfromnumber (s_point [i], p, &pr, &pc, &sr, &sc) ; get xyfromspotnumber (spoint [i], p, &x, &y) ; pn=getpinnumberfromspotnumber (spoint [i], p) ;

d=sqrt ( ( ( (double) b [i]. box-row - (mi [0]. rowoffset [pn]))-y) * ( ( (double) b [i]. box-row - (mi [0]. rowoffset [pn]))-y) + ( ( (double) b [i]. box_column-(mi[0].col_offset[pn]))-x) * ( ( (double) b [i]. boxcolumn- (mi [0]. coloffset [pn]))-x)) ; b [i]. box_distance_from_grid=d; if (d> (double) p [0]. pin_rattle) b [i]. boxtype=NOTINGRID ; mi [0]. number [pn]--; mi [0]. distance [[pn]=mi[0]. distance [pn]-d ; mi [0]. intensity [pn] =mi [0]. intensity [pn]-map_intensity_f unction (&b [i]) ; b [i]. pinrow=pr ; b [i]. pincolumn=pc ; b [i]. spot_row=sr ; b [i]. spot_column=sc ; free (s_point) ; if (debug) for (pn=0 ; pnnum_pins ; pn++)

printf (pin='-. r=%5i c=%5i number=%5i distance=o+e intensity=%+e\n", pn, mi [0]. rowoffset [pn], mi [0]. col_offset[pn], mi [0]. number [pn], mi [0]. distance [pn], mi [0]. intensity [pn]) ; /* pn=0 ; for (i=0 ; i<numboxes ; i++) if (b [i]. boxtype==INGRID) pn++ ; printf ("#%i boxes assigned to grid positions... \n", pn) ; */ void free-map-image (struct map-image *mi) if (mi [0]. image ! =NULL) {free (mi [0]. image) ; mi [0]. image=NULL ; if (mi [0]. row_offset!=NULL) {free (mi [0]. rowoffset) ; mi [0]. rowoffset=NULL ; if (mi [0]. col-offset ! =NULL) {free (mi [0]. col-offset) ; mi [0]. coloffset=NULL ;

if (mi [0]. intensity ! =NULL) {free (mi [0]. intensity) ; mi [0]. intensity=NULL ; if (mi [0]. distance ! =NULL) {free (mi [0]. distance) ; mi [0]. distance=NULL ; if (mi [0]. number ! =NULL) {free (mi [0]. number) ; mi [0]. number=NULL ; if (mi [0]. occupied ! =NULL) {free (mi [0]. occupied) ; mi [0]. occupied=NULL ; } if (mi [0]. occupied_distance!=NULL) {free (mi [0]. occupied_distance) ; mi [0]. occupieddistance=NULL ; void map-spots (struct image_data *our_image, struct mapspotsparams *m, struct printer *p) f struct map-image mi ;

double xl, x2, yl, y2 ; int range_row, range col ; mi. image=NULL ; mi. row offset=NULL ; mi. col_offset=NULL ; mi. intensity=NULL ; mi. distance=NULL ; mi. occupied=NULL ; mi. occupieddistance=NULL ; createmapimage (&mi, m, p) ; #ifdef WET DOT #else map-image remove missing (&mi, p) ; #endif /* Warning if you do not call this function mapping will fail*/ get_internal_width_and_height(&mi) ; if (m [0]. debug)

writemapppm ("mapspotsimage. ppm", mi. width, mi. height, mi. image) ; if (m [o]. do coarse) {printf ("#Coarse\n") ; map_coarse (our_image, &mi, p, m [0]. increment_coarse, m [0]. debug) ; if (m [0]. do-fine) {printf ("&num Fine\n") ; map_fine (our-image, &mi, p, m [0]. increment_fine, m [0]. range_fine_row, m [0]. range_fine_column, m [0]. debug) ; -if (m [0]. docoarsepinbypin) if ((m[0].range_coarse_pin_by_pin_col_autoselect==1) && (p [0]. pinsperrow>l)) get_xyfromspotandpin(0. 0, 0. 0, ( (double) (p->spotsperrow-l)), 0. 0, p, &xl, &yl) ; get_xyfromspotandpin(1. 0, 0. 0, 0. 0, 0. 0, p, &x2, &y2) ; range_col= (int) (0. 45* (x2-xl)) ; if (range_col<l)

range col=m [0]. rangecoarsepinbypincolumn ; } else range_col=m[0].range_coarse_pin_by_pin_column ; if ((m[0].range_coarse_pin_by_pin_row_autoselect==1) && (p [0]. pinspercolumn>l)) { get xyfromspotandpin (0. 0, 0. 0, 0. 0, (double) (p [0]. spots_per_column-1), p, &xl, &yl) ; getxyfromspotandpin (0. 0, 1. 0, 0. 0, 0. 0, p, &x2, &y2) ; range_row= (int) (0. 45* (y2-yl)) ; if (rangerow<l) range_row=m[0].range_coarse_pin_by_pin_row ; else range_row=m[0].range_coarse_pin_by_pin_row ; printf ("#Coarse pin by pin, range_row=%i range_column=%i\n", range_row, range_col) ; map_pin_by_pin(our_image, &mi, p, m [0]. increment_coarse_pin_by_pin, range-row, range-col, m [0]. debug) ;

if (m [0]. dofinepinbypin) {printf ("#Fine pin by pin\n") ; map_pin_by_pin (our-image, &mi, p, m [0]. incrementfinepinbypin, m [0]. rangefinepinbypinrow, m [0]. range_fine_pin_by_pin_column, m [0]. debug) ; if (m [0]. do distance) { printf("#Distance minimization\n") ; map_distance_minimization(our_image, &mi, p, m [0]. increment_distance, m [0]. range_distance_row, m [0]. range_distance_column, m [0]. debug) ; } printf ("#Perform map assignments\n") ; map_assign (our-image, &mi ; p, m [0]. debug, m [0]. snap_negatives_to_grid) ; free map image (&mi) ;

mask. c #include"defs. h" double gaussian (double r, double r_max) return (exp (-6. 0* (r*r)/ (rmax*rmax))) ; double gaussianring (double r, double center, double r_max) return (exp (-6. 0* ((r-r_center) * (r-r_center))/(r_max*r_ma x))) ; double *gaussianringmask (int rring, int r-int, int zero) { double *mask ; int width ; double dist ; double middle ; int row, column, pixel ; width = 2*r int-1 ;

mask = (double *) malloc (sizeof (double) * (width*width)) ; middle = (double) (rint-l) ; printf ("#width = %i, rring = % i\n", width, rring) ; for (row=0 ; row<width ; row++) { printf ("&num ") ; for (column=0 ; column<width ; column++) dist = sqrt ( (middle- ( (double) row)) * (middle- ( (double) row)) + (middle- ( (double) column)) * (middle- ( (double) column))) ; pixel = row*width+column ; if (dist<=r_ring+2) { mask [pixel] =gaussianring (dist, (double) rring, (double) zero) ; else mask [pixel] =0 ; printf ("% i", (int) (mask [pixel] *9. 0)) ; printf ("\n") ;

return (mask) ; double *gaussianringmaskcut (int rring, int r-int, int zero r, int cutoff) double *mask ; int width ; double dist ; double middle ; int row, column, pixel ; width = 2*r int-l ; mask = (double *) malloc (sizeof (double) * (width*width)) ; middle = (double) (rint-l) ; printf ("#width = %i, rring = %i\n", width, rring) ; for (row=0;row<width ; row++) { printf ("&num ") ; for (column=0 ; column<width ; column++) dist = sqrt ( (middle- ( (double) row)) * (middle- ( (double) row)) + (middle- ( (double) column)) * (middle- ( (double) column))) ; pixel = row*width+column ;

if (dist<=cutoff) mask [pixel] =gaussian_ring (dist, (double) rring, (double) zero r) ; else mask [pixel] =0 ; printf ("%i", (int) (mask [pixel] *9. 0)) ; printf ("\n") ; return (mask) ; double *circle_filled_small (int radius) double *mask ; int width ; double dist ; double middle ; int row, column, pixel ; width = 2*radius-l ; mask = (double *) malloc (sizeof (double) * (width*width)) ;

middle = (double) (radius-1) ; for (row=0 ; row<width ; row++) for (column=0 ; column<width ; column++) dist = sqrt ( (middle- ( (double) row)) * (middle- ( (double) row)) + (middle- ( (double) column)) * (middle- ( (double) column))) ; pixel = row*width+column ; if (dist< (double) (radius)) mask [pixel] =1. 0 ; else mask [pixel] =0. 0 ; } return (mask) ; double *box filled small (int radius) double *mask ; int width ; int row, column, pixel ;

width = 2*radius-1 ; mask = (double *) malloc (sizeof (double) * (width*width)) ; for (column=0 ; column< (width*width) ; column++) mask [column] =0. 0 ; for (row=0 ; row<width ; row++) for (column=0 ; column<width ; column++) { pixel = row*width+column ; mask [pixel] =1. 0 ; return (mask) ; double *box filled big (int radius) { double *mask ; int width ; int row, column, pixel ; width = 2*radius+1 ; mask = (double *) malloc (sizeof (double) * (width*width)) ; for (column=0 ; column< (width*width) ; column++) mask [column] =0. 0 ; for (row=0row<width ; row++) f

for (column=0 ; column<width ; column++) pixel = row*width+column ; mask [pixel] =1. 0 ; return (mask) ; double *box-big (int radius) double *mask ; int width ; int row, column, pixel ; width = 2*radius+1 ; mask = (double *) malloc (sizeof (double) * (width*width)) ; for (column=0 ; column< (width*width) ; column++) mask [column] =0. 0 ; /*top and bottom*/ for (column=0 ; column<width ; column++) mask [column] =1. 0 ; mask [(width-l) *width+column] =1. 0 ; /*edges*/

for (row=l ; row< (width-l) ; row++) { pixel = row*width ; mask [pixel] =1. 0 ; pixel = row*width+ (width-l) ; mask [pixel] =1. 0 ; return (mask) ; double *box big thick (int radius, int thickness) { double *mask ; int width ; int row, column, pixel ; width = 2*radius+1 ; mask = (double *) malloc (sizeof (double) * (width*width)) ; for (column=0 ; column< (width*width) ; column++) mask [column] =0. 0 ; /*top and bottom*/ for (column=0 ; column<width ; column++) for (row=0 ; row<thickness ; row++) { mask [row*width+column] =1. 0 ; mask [(width-l-row) *width+column] =1. 0 ;

/*edges*/ for (row=l ; row< (width-l) ; row++) for (column=0 ; column<thickness ; column++) pixel = row*width+column ; mask [pixel] =1. 0 ; pixel = row*width+ (width-l-column) ; mask [pixel] =1. 0 ; } return (mask) ; } double *box small (int radius) { double *mask ; int width ; int row, column, pixel ; width = 2*radius-1 ; mask = (double *) malloc (sizeof (double) * (width*width)) ; for (column=0 ; column< (width*width) ; column++) mask [column] =0. 0 ;

/*top and bottom*/ for (column=oscolumncwidth ; column++) { mask [column] =1. 0 ; mask [(widthy-1)*width+column] =1. 0 ; /*edges*/ for (row=l ; row< (width-l) ; row++) pixel = row*width ; mask [pixel] =1. 0 ; pixel = row*width+ (width-l) ; mask [pixel] =1. 0 ; return (mask) ; double *circlefilledbig (int radius) { double *mask ; int width ; double dist ; double middle ; int row, column, pixel ; width = 2* (radius) +1; mask = (double *) malloc (sizeof (double) * (width*width)) ;

middle = (double) (radius) ; for (row=0 ; row<width ; row++) for (column=0 ; column<width ; column++) dist = sqrt ( (middle- ( (double) row)) * (middle- ( (double) row)) + (middle- ( (double) column)) * (middle- ((double) column))) ; pixel = row*width+column ; if (dist<= (double) (radius)) mask [pixel] =1. 0 ; else mask [pixel] =0. 0 ; return (mask) ; double *circle big (int radius) double *mask ; int width ; double dist ;

double middle ; int row, column, pixel ; int on ; width = 2* (radius) +1 ; mask = (double *) malloc (sizeof (double) * (width*width)) ; for (pixel=0 ; pixel<width*width ; pixel++) mask [pixel] =0. 0 ; middle = (double) (radius) ; /* rows */ for (row=0 ; row<width ; row++) { on = 0 ; column=0 ; /* from left */ while ( (column<width) && (on==0)) dist = sqrt ( (middle- ( (double) row)) * (middle- ( (double) row)) + (middle- ( (double) column)) * (middle- ( (double) column))) ; pixel = row*width+column ; if ( (dist<= (double) (radius))) on = 1 ; mask [pixel] =1. 0 ;

column++ ; on = 0 ; column=width-l ; /* from right */ while ( (column>=0) && (on==0)) dist = sqrt ( (middle- ( (double) row)) * (middle- ( (double) row)) + (middle- ( (double) column)) * (middle- ( (double) column))) ; pixel = row*width+column ; if ( (dist<= (double) (radius))) on = 1 ; mask [pixel] =1. 0 ; column-- ; /* columns */ for (column=0 ; column<width ; column++) on = 0 ; row=0 ; /* top */ while ( (row<width) && (on==0))

dist = sqrt ( (middle- ( (double) row)) * (middle- ( (double) row)) + (middle- ( (double) column)) * (middle- ( (double) column))) ; pixel = row*width+column ; if ( (dist<= (double) (radius))) on = 1 ; mask [pixel] =1. 0 ; row++ ; on = 0 ; row=width-l ; /* from bottom */ while ( (row>=0) && (on==0)) dist = sqrt ( (middle- ( (double) row)) * (middle- ( (double) row)) + (middle- ( (double) column)) * (middle- ( (double) column))) ; pixel = row*width+column ; if ( (dist<= (double) (radius))) on on = 1 ; mask [pixel] =1. 0 ; }

row- return (mask) ; double *circle big thick (int passed_radius, int thickness) { double *mask ; int width ; double dist ; double middle ; int row, column, pixel ; int on ; double radius ; width = 2*(passed_radius)+1 ; mask = (double *) malloc (sizeof (double) * (width*width)) ; for (pixel=0pixelowidth*width ; pixel++) mask [pixel] =0. 0 ; middle = (double) (passed_radius) ; for (radius= (middle-thickness+l) ; radius<=middle ; radius+= 0. 5) /* rows */ for (row=0 ; row<width ; row++)

{ on = 0 ; column=0 ; /* from left */ while ( (column<width) && (on==0)) dist = sqrt ( (middle- ( (double) row)) * (middle- ( (double) row)) + (middle- ( (double) column)) * (middle- ( (double) column))) ; pixel = row*width+column ; if ( (dist- (double) radius) < (0. 5)) on = 1 ; mask [pixel] =1. 0 ; column++ ; on = 0 ; column=width-l ; /* from right */ while ( (column>=0) && (on==0)) dist = sqrt ( (middle- ( (double) row)) * (middle- ( (double) row)) + (middle- ( (double) column)) * (middle- ( (double) column))) ; pixel = row*width+column ;

if ( (dist- (double) radius) < (0. 5)) on = 1 ; mask [pixel] =1. 0 ; column-- ; /* columns */ for (column=0 ; column<width ; column++) on = 0 ; row=0 ; /* top */ while ( (row<width) && (on==0)) dist = sqrt ( (middle- ( (double) row)) * (middle- ( (double) row)) + (middle- ( (double) column)) * (middle- ( (double) column))) ; pixel = row*width+column ; if ( (dist- (double) radius) < (0. 5)) on = 1 ; mask [pixel] =1. 0 ; row++ ;

on = 0 ; row=width-l ; /* from bottom */ while ( (row>=0) && (on==0)) dist = sqrt ( (middle- ( (double) row)) * (middle- ( (double) row)) + (middle- ( (double) column)) * (middle- ( (double) column))) ; pixel = row*width+column ; if ( (dist- (double) radius) < (0. 5)) on on = 1 ; mask [pixel] =1. 0 ; row-- ; return (mask) ; double *circle small (int radius) double *mask ; int width ; double dist ;

double middle ; int row, column, pixel ; int on ; width = 2* (radius)-1 ; mask = (double *) malloc (sizeof (double) * (width*width)) ; for (pixel=0 ; pixel<width*width ; pixel++) mask [pixel] =0 ; middle = (double) (radius-1) ; /* rows */ for (row=0 ; row<width ; row++) /* from left */ on = 0 ; column=0 ; while ( (column<width) && (on==0)) dist = sqrt ( (middle- ( (double) row)) * (middle- ( (double) row)) + (middle- ( (double) column)) * (middle- ((double) column))) ; pixel = row*width+column ; if ( (dist< (double) (radius))) on on = 1 ; mask [pixel] =1. 0 ; }

column++ ; /* from right */ on = 0 ; column=width-1 ; while ( (column>=0) && (on==0)) dist = sqrt ( (middle- ( (double) row)) * (middle- ( (double) row)) + (middle- ( (double) column)) * (middle- ( (double) column))) ; pixel = row*width+column ; if ( (dist< (double) (radius))) on on = 1 ; mask [pixel] =1. 0 ; column-- ; } /* columns */ for (column=0 ; column<width ; column++) { on = o ; row=0 ; /* top */

while ( (row<width) && (on==0)) dist = sqrt ( (middle- ( (double) row)) * (middle- ( (double) row)) + (middle- ( (double) column)) * (middle- ( (double) column))) ; pixel = row*width+column ; if ( (dist< (double) (radius))) on on = 1 ; mask [pixel] =1. 0 ; row++ ; on = 0 ; row=width-l ; /* from bottom */ while( (row>=0) && (on==0)) { dist = sqrt ( (middle- ( (double) row)) * (middle- ( (double) row)) + (middle- ( (double) column)) * (middle- ( (double) column))) ; pixel = row*width+column ; if ( (dist< (double) (radius))) on = 1 ; mask [pixel] =1. 0 ;

row--; return (mask) ; int mask-area (int n, double * mask) int i ; int area=0 ; for (i=0 ; i<n ; i++) if (mask [i] >0. 0000001) area++ ; return (area) ; void get-integration info (struct integration_params * iparams) { if (iparams->mask_flag==l) if (iparams->mask_file_flag==1) printf ("WARNING : mask file reading not implemented yet ! \n") ;

printf ("defaulting to no mask and square integration\n") ; iparams->maskflag=0 ; iparams->square_flag=1 ; else if (iparams->circle_flag==1) iparams->mask = circle_filled_big(iparams->integration_radius) ; iparams->perimetermask = circlebig (iparams->integrationradius) ; iparams->maskwidth = 2*iparams->integration_radius+1 ; else if (iparams->square_flag==1) iparams->mask = boxfilledbig (iparams->integrationradius) ; iparams->perimetermask = boxbig (iparams->integration radius) ; iparams->maskwidth = 2*iparams->integration_radius+1 ; else

printf ("WARNING : mask specified but with no shape given ! \n") ; printf (" defaulting to no mask and square integration\n") ; iparams->maskflag=0 ; iparams->square_flag=1 ; } void get_background_mask (struct background,. * bparams) { if (bparams->maskflag==l) if (bparams->circle_flag==l) { bparams->mask = circle_big_thick(bparams->background_radius,bparams->b a ckgroundframewidth) ; bparams->maskwidth = 2*bparams->backgroundradius+l ; else if (bparams->square_flag==l)

bparams->mask = <BR> boxbigthick (bparams->backgroundradius, bparams->backgroun ( bparams->maskwidth = 2*bparams->background_radius+1 ; else printf ("WARNING : mask specified for backbround but with no shape given ! \n") ; printf (" defaulting to no mask and square shape\n") ; bparams->maskflag=0 ; bparams->square_flag=l ; output data. c &num include"defs. h" /*this simply removes boxes that do not belong to a grid point*/ void transfer-spots to grid (struct image-data * image, struct printer *p)

{int i, *j, *k, 1, sr, sc, pr, pc, n, numboxes ; struct box * grid_box, * boxes ; boxes=image->boxes ; numboxes=image->numboxes ; /* sort the boxes by pin row/column box/row column */ k= (int *). malloc (sizeof (int) *nbboxes) ; if (k==NULL) {printf ("Failed malloc in transfer_spots_to_grid... \n") ; exit (-l) ; } for (i=0 ; i<numboxes ; i++) k [i] =i ; hsort (boxes, k, numboxes, sizeof (struct box), data_sort_compare) ; /* get the number of grid points */ n=p [0]. spotsperrow * p [0]. spotspercolumn * p [0]. pinsperrow * p [0]. pinspercolumn ; j= (int *) malloc (sizeof (int) *n) ; if (j==NULL)

{printf ("Failed malloc in transferspotstogrid... \n") ; _ exit (-l) ; for (i=0 ; i<n ; i++) j [i] =-l ; for (i=0 ; (i<numboxes) && (boxes [k [i]]. boxtype==INGRID) ; i++) 1=get spot number (boxes [k [i]]. pinrow, boxes [k [i]]. pin_column, boxes [k [i]]. spot-row, boxes [k [i]]. spot_column, p) ; j [1] =k [i] ; free (k) ; grid_box= (struct box *) malloc (n*sizeof (struct box)) ; if (gridbox==NULL) {printf ("Failed malloc in transfer_spots_to_grid...\n") ; exit (-l) ; for (pr=0 ; pr<p [0]. pins per-column ; pr++) for (pc=0 ; pc<p [0]. pins-per-row ; pc++) for (sr=0 ; sr<p [0]. spots_per_column ; sr++)

for (sc=0 ; sc<p [0]. spotsperrow ; sc++) - { 1=get_spot_number (pr, pc, sr, sc, p) ; if (j Ill ! = (-l)) memcpy (&grid_box[1], &boxes [j [l]], sizeof (struct box)) ; else { grid_box[1].spot_row=sr ; grid_box[1].spot_column=sc ; grid_box[1].pin_row=pr ; grid_box[1].pin_column=pc ; grid_box[1].box_type=NOT_IN_GRID ; /*since create-box might not be called, need to do this to prevent free crash*/ gridbox [l]. common=NULL ; grid_box[1].wrt_reference=NULL ; gridbox [l]. reference=NULL ; free (j) ; free (boxes) ; image->boxes=gridbox ; image->numboxes=n ; /*This fills in box structures that are empty because of fill-in empty boxes*/ void fillinemptyboxes (struct image-data * image,

struct printer * p, struct integration_params * iparams, struct integration_params * iparams_small, struct background_params * bparams, struct spot_finding_params * sfparams) {int num_pins, i, row, col, pn, n_fillins=0 ; double x, y ; struct box * s ; s = image->boxes ; num_pins=p[0].spots_per_row * p [0]. spots-per-column * p [0]. pins_per_row * p [0]. pins per-column ; for (i=0 ; i<numpins ; i++) get_xyfromspotandpin (s [i]. pin_column, s [i]. pin row, s [i]. spot_column, s [i]. spot_row, p, &x, &y) ; pn=s [i]. pin_row* (p [0]. pins_per_row) +s [i]. pin_column ; row= ( (int) (y+0. 5)) + p [0]. rowoffsets [pn] ; col= ( (int) (x+0. 5)) + p [0]. columnoffsets [pn] ; if (s [i]. boxtype==NOTINGRID) nfillins++ ;

if ((row>(-1)) && (col> (-l)) && (row<image[0].height) && (col<image[0]. width)) create-box (image, row, col, iparams, iparams_small, bparams, &s [i]) ; s [i]. boxtype=INGRID ; get_largest_spot_statistics (image, &s [i], sfparams) ; s [i]. box_distance_from_grid=0. 0 ; else else /*if the program gets here, the box is off the image*/ /*setting box type to NOT-IN-GRID only because there is no*/ /*other reasonable choice right now*/ /*should correct this in the future*/ s [i]. boxtype=NOTINGRID ; s [i].box_row=row ; s [i]. boxcolumn=col ; s [i]. spot-distance-from-grid=0. 0 ; s [i]. box_distance_from_grid=0. 0 ; s [i]. distancefromspottobox=DBL MAX ; s [i]. num_spots=0 ;

if (s [i]. numspots>0) { s [i]. spot_distance_from_grid=sqrt((s[i].spot_ybar-((dou ble) row)) * (s [i]. spot_ybar-((double) row)) + (s [i]. spot_xbar-((double) col)) * (s [i]. spot_xbar-((double) col))) ; else s [i]. spot_distance_from_grid=DBL_MAX ; image [0]. numboxesfilledin=nfillins ; printf ("#%i boxes filled in... \n", n_fillins) ; int statflagscheck (struct statistics-flags * flags) { int flagcheck=0 ; if (flags->average==l) flag_check++ ; if (flags->std_dev==1) flag_check++ ; if (flags->median==l) flag_check++ ; if (flags->average_one_sd==l) flag_check++ ; if (flags->average_two_sd==l) flag-check++ ; if (flags->area==l) flag-check++ ; if (flags->area one-sd==l) flag_check++ ;

if (flags->area_two_sd==1) flag_check++ ; if (flags->area_zero==1) flag_check++ ; if (flags->area_saturated==1) flag_check++ ; if (flags->min==1) flag_check++ ; if (flags->max==l) flag_check++ ; return (flag check) ; void stat_f. lags_labels (struct statistics-flags * flags, FILE * f) { if (flags->average==l) fprintf (f,"Average\t") ; if (flags->std dev==l) fprintf (f, "Std_Dev\t") ; if (flags->median==l) fprintf (f, "Median\t") ; if (flags->average_one_sd==1) fprintf (f, "Avg-l-SD\t") ; if (flags->average_two_sd==l) fprintf (f, "Avg-2-SD\t") ; if (flags->area==l) fprintf (f,"Area\t") ; if (flags->area-one_sd==1) fprintf (f, "Area-l-SD\t") ; if (flags->area_two-sd==l) fprintf (f, "Area-2-SD\t") ; if (flags->area_zero==1) fprintf (f, "Area-Zero\t") ; if (flags->area_saturated==1) fprintf (f, "Area-Satr\t") ; if (flags->min==l) fprintf (f, "Min\t") ; if (flags->max==l) fprintf (f,"Max\t") ;

void statflags values (struct statistics_flags * flags, struct statistics * stats, FILE * f) { if (flags->average==1) fprintf (f, "%6i=t", ( (int) stats->average)) ; if (flags->std_dev==1) fprintf (f, "%6i\t", ( (int) *stats->stddev)) ; if (flags->median==1) fprintf (f, "%6i\t", ((int) stats->median)) ; if (flags->averageonesd==l) fprintf (f, "%6i\t", ((int) stats->average_one_sd)) ; if (flags->averagetwosd==l) fprintf (f, "%6i\t", ((int) stats->average_two-sd)) ; if (flags->area==1) fprintf (f, "%6i\t", ( (int) stats->area)) ; if (flags->areaonesd==l) fprintf (f, "%6i\t", ((int) stats->area_one_sd)) ; if (flags->area_two_sd==1) fprintf(f, "%6i\t", ((int) stats->area_two_sd)) ; if (flags->area_zero==1) fprintf (f, "%6i\t", ((int) stats->area_zero)) ; if (flags->area_saturated==1) fprintf(f, "%6i\t", ((int) stats->area_saturated)) ; if (flags->min==1) fprintf (f, "%6i\t", ( (int) stats->min)) ; if (flags->max==1) fprintf (f, "%6i\t", ( (int) stats->max)) ;

} void statflagsdvalues (struct statistics_flags * flags, struct statistics * stats, FILE * f) { if (flags->average==l) fprintf (f, "%10.5f\t", (stats->average)) ; if (flags->std dev==l) fprintf (f, "%10.5f\t", (stats->stddev)) ; if (flags->median==l) fprintf (f, "%10.5f\t", ( stats->median)) ; if (flags->average_one_sd==1) fprintf (f, "%10. 5f\t", ( stats->average_one_sd)) ; if (flags->average_two_sd==1) fprintf (f, "%10. 5f\t", (stats->averagetwosd)) ; if (flags->area==l) fprintf (f, "%6i\t", ( (int) stats->area)) ; if (flags->area_one_sd==1) fprintf (f, "%6i\t", ((int) stats->area_one_sd)) ; if (flags->area two-sd==l) fprintf (f, "%6i\t", ((int) stats->area_two_sd)) ; if (flags->area_zero==1) fprintf (f, "%6i\t", ((int) stats->area_zero)) ; if (flags->area saturated==l) fprintf (f, "%6i\t", ((int) stats->area_saturated)) ; if (flags->min==l) fprintf (f, "%10.5f\t", (stats->min)) ; if (flags->max==l) fprintf (f, "%10.5f\t", (stats->max)) ;

void write-data (int image, int numimages, struct image_deta **the_images, struct printer *p, struct output data * flags, char *output-path) {int i, *j, *k, l, n, sr, sc, pr, pc, numboxes, flag_check, pn, current_spot_type ; char * fname ; FILE * f ; struct box * boxes, * sgb ; struct image data * our-image ; char * ext=". txt" ; int is ref=0 ; if (image==0) is ref=1 ; our_image=the_images[image] ; boxes=our-image [0]. boxes ; numboxes=ourimage [0]. numboxes ; /* change the path and put an extension on the output filename */

fname = get-new_file_name (our_image[0].file_name, output_path, ex t) ; printf ("%s\n", fname) ; f=fopen (fname,"w") ; if (f==NULL) { printf ("Could not open output data file ! \n") ; return ;. fprintf (f,"#ExpressArray version") fprintf (f, EXPRESS ARRAY VERSION) ; fprintf (f,"\n") ; fprintf (f,"#Number of images in analysis\t%i\n", numimages) ; fprintf (f,"&num Reference image\t") ; if (image==0) fprintf (f,"TRUE\n") ; else fprintf (f,"FALSE\n") ; fprintf (f,"&num Reference image filename\t%s\n", the_images [0]->filename) ; fprintf (f,"&num Analyzed image filename\t%s\n", the-images [image]->filename) ; for (i=l ; i<num-images ; i++) if (image ! =i)

fprintf (f,"#Other image analyzed with this reference\t%s\n", the_images[i]->file_name) ; fprintf (f,"&num SubGrid format\t") ; if (p->hexagonal==0) fprintf (f,"Rectangular\n") ; if (p->hexagonal==l) fprintf (f,"Hexagonall\n") ; if (p->hexagonal==2) fprintf. (f,"Hexagonal2\n") ; if (p->hexagonal==3) fprintf (f,"Hexagonal3\n") ; if (p->hexagonal==4) fprintf (f,"Hexagonal4\n") ; if (f==NULL) {printf ("Failed to open the output file in n write_data...\n") ; return ; k= (int *) malloc (sizeof (int) *nbboxes) ; if (k==NULL) {printf ("Failed malloc in write data... \n") ; exit (-l) ; for (i=0 ; i<numboxes ; i++)

k [i] =i ; hsort (boxes, k, num_boxes, sizeof (struct box), data-sort-compare) ; n=p [0]. spotsperrow * p [0]. spots_per_column * p [0]. pins per row * p [0]. pinspercolumn ; j= (int *) malloc (sizeof (int) *n) ; if (j==NULL) {printf ("Failed malloc in write_data... \n") ; exit (-l) ; for (i=0 ; i<n ; i++) j [i] =-l ; for (i=0 ; (i<numboxes) && (boxes [k [i]]. boxtype ! =NOTINGRID) ; i++) {l=get_spot_number (boxes [k [i]]. pin-row, boxes [k [i]]. pin-column, boxes [k [i]]. spot-row, boxes [k [i]].spot_column, p) ; j [l] =k [i] ; } free (k) ; /* First Row of Column Headers */

if (flags->pin_row==1) fprintf(f, "\t") ; if (flags->pin_column==1) fprintf(f, "\t") ; if (flags->spot_row==1) fprintf (f,"\t") ; if(flags0->spot_column==1) fprintf (f,"\t") ; if (flags->spot_number==1) fprintf (f,"\t") ; if (flags->spot_type==l) fprintf (f,"\t") ; if (flags->grid_row==1) fprintf (f,"\t") ; if (flags->grid_column==1) fprintf (f,"\t") ; if (flags->region_flag==1) { flag_check=stat_flags_check (&flags->region) ; if (flags->box_row==1) flag_check++ ; if (flags->box_column==1) flag_check++ ; if (flags->box_dist_to_grid==1) flag_check++ ; if (flag_check==0) flags->region_flag=0; else { fprintf (f, "Region"); for (i=0 ; i<flagcheck ; i++) fprintf (f,"\t") ; if (flags->spot_flag==l) flag_check=stat_flags_check (&flags->spot) ; if (flags->spot_ybar==l) flag_check++ ; if (flags->spot_xbar==1) flag_check++ ; if (flags->spot_perimeter==l) flag-check++ ;

if (flags->spot_width==1) flag-check++ ; if (flags->spot_height==1) flag_check++ ; if (flags->spot_rbar==1) flag_check++ ; if (flags->spot_rmin==l) flag-check++ ; if (flags->spot_rmax==1) flag_check++ ; if (flags->spot_dist_to_grid==1) flag_check++ ; if (flag_check==0) flags->spot_flag=0 ; else { fprintf (f,"Spot") ; for (i=0 ; i<flagcheck ; i++) fprintf (f, "\t"); } if (flags->background_flag==1) flag_check=stat-flags_check (&flags->background) ; if (flag check==0) flags-background flag=0 ; else { fprintf (f,"Background") ; for (i=0 ; i<flag_check ; i++) fprintf (f, "\t") ; /* Common unsaturated data for multiimage analysis (pairwise) */ if ( ! is-ref)

if (flags->region_wrt_reference_flag==1) flag_check=stat_flags_check(&flags->region_wrt_referenc e) ; if (flag check==0) flags->regionwrtreferenceflag=0 ; else { fprintf (f,"Region Unsaturated (pairwise)") ; for (i=0 ; i<flagcheck ; i++) fprintf (f,"\t") ; if (flags->spot_wrt_reference_flag==1) { flag_check=stat_flags_check (&flags->spot_wrt_reference) ; if (flag_check==0) flags->spotwrtreferenceflag=0 ; else { fprintf (f,"Spot Unsaturated (pairwise)") ; for (i=0 ; i<flagcheck ; i++) fprintf (f, "\t") ; } if (flags->background_wrt_reference_flag==1) flag_check=stat_flags_check (&flags->backgroundwrt reference) ;

if (flag check==0) flags->background_wrt_reference_flag=0 ; else { fprintf (f,"Background Unsaturated (pairwise)") ; for (i=0 ; i<flagcheck ; i++) fprintf (f,"\t") ; } if (flags->ratiowrtreferenceflag==l) flag_check=stat_flags_check (&flags->ratiowrtreference ) i if (flags->row shift==l) flagcheck++ ; if (flags->col_shift==l) flag_check++ ; if (flags->slope==l) flag-check++ ; if (flags->intercept==l) flag_check++ ; if (flags->R==l) flag-check++ ; if (flag_check==0) flags->ratio_wrt_reference_flag=0 ; else { fprintf (f,"Ratio Unsaturated (pairwise)") ; for (i=0 ; i<flag_check ; i++) fprintf (f,"\t".) ; /* reference Common unsaturated data for multiimage analysis (pairwise) */

if (flags->region_reference_flag==1) flag_check=stat_flags_check(&flags->region_reference) ; if (flag_check==0) flags->regionreferenceflag=0 ; else { fprintf (f,"Region Reference Unsaturated (pairwise)") ; for (i=o ; i<flagcheck ; i++) fprintf (f,"\t") ; if (flags->spot_reference_flag==1) flag_check=stat_flags_check(&flags->spot_reference) ; if (flag check==0) flags->spotreferenceflag=0 ; else { fprintf (f,"Spot Reference Unsaturated (pairwise)") ; for (i=0 ; i<flag_check ; i++) fprintf (f,"\t") ; if (flags->background reference_flag==l) flag check=stat flags_check (&flags->background ref erence) ;

if (flag-check==0) flags->background_wrt_reference_flag=0 ; else { fprintf (f,"Background Reference Unsaturated (pairwise)",) ; for (i=0 ; i<flag_check ; i++) fprintf (f,"\t") ; /* Common unsaturated data for multiimage analysis */ if (flags->region_common_flag==1) flag_check=stat_flags_check(&flags->region_common) ; if (flagcheck==0) flags->regioncommonflag=0 ; else { fprintf (f,"Region Common Unsaturated") ; for (i=0 ; i<flagcheck ; i++) fprintf (f,"\t") ; } if (flags->spot_common_flag==1) flag_check=stat_flags_check (&flags->spot_common) ; if (flag-check==0) flags->spot_common_flag=0 ; else {

fprintf (f,"Spot Common Unsaturated") ; for (i=0 ; i<flag_check ; i++) fprintf (f,"\t") ; } if (flags->background_common_flag==1) flag_check=stat_flags_check (&flags->background_common) ; if (flag_check==0) flags->backgroundcommonflag=0 ; else { fprintf (f,"Background Common Unsaturated") ; for (i=0 ; i<flag_check ; i++) fprintf (f,"\t") ; if ((flags->ratio_common_flag==1) && (!is_ref)) { flag_check=stat_flags_check(&flags->ratio_common) ; if (flag_check==0) flags->ratiocommonflag=0 ; else { fprintf (f,"Ratio Common Unsaturated") ; for (i=0 ; i<flagcheck ; i++) fprintf (f,"\t") ;

/* end common unsaturated for multi-image analysis */ if (p->geneidcolumnheadings ! =NULL) { fprintf (f,"Gene ID Information\n") ; else fprintf (f,"\n") ; /*Second Row of Column Headers*/ if (flags->pin row==l) fprintf (f,"SubRow\t") ; if (flags->pin column==l) fprintf (f,"SubCol\t") ; if (flags->spot_row==1) fprintf (f,"SpotRow\t") ; if (flags->spot column==l) fprintf (f,"SpotCol\t") ; if (flags->spot number==l) fprintf (f,"SpotNum\t") ; if (flags->spot_type==l) fprintf (f,"SpotType\t") ; if (flags->grid_row==1) fprintf(f, "Grid Row\t") ; if (flags->grid column==l) fprintf (f,"Grid Col\t") ; if (flags->region-flag==l) { if (flags->box_row==10 fprintf (f, "Row\t") ; if (flags->box_column==1) fprintf (f, "Col\t"); if (flags->box_dist_to_grid==1) fprintf (f, "Dist-to-Grid\t") ; stat_flags_labels (&flags->region, f) ;

if (flags->spot_flag==l) if (flags->spot_ybar==l) fprintf (f, "Row\t") ; if (flags->spot_xbar==1) fprintf (f, "Col\t") ; if (flags->spot_dist_to_grid==l) fprintf (f, "Dist-to-Grid\t") ; statflagslabels (&flags->spot, f) ; if (flags->spot_perimeter==1) fprintf (f, "Perimeter=t") ; if (flags->spot_width==1) fprintf (f, "Width\t") ; if (flags->spot_height==1) fprintf(f, "Height\t") ; if (flags->spot_rbar==1) fprintf (f,"Avg Radius\t") ; if (flags->spot_rmin==l) fprintf (f,"Min Radius\t") ; if (flags->spot rmax==l) fprintf (f,"Max Radius\t") ; if (flags->background_flag==1) { stat_flags_labels (&flags->background, f) ; }

if (!is_ref0 { if (flags->region_wrt_reference_flag==1) statflagslabels (&flags->regionwrtreference, f) ; } if(flags->spot_wrt_reference_flag==1) stat_flags_lables(&flags->spot_wrt_reference, f) ; if (flags->background_wrt_reference_flag==1) stat_flags_labels(&flags->background_wrt_reference, f) ; if (flags->ratio wrt_reference-flag==l) stat_flags_labels (&flags->ratiowrtreference, f) ; if (flags->row shift==l) fprintf (f, "Row-shift\t") ; if (flags->col_shift==l) fprintf (f, "Column-shift\t") ; if (flags->slope==l) fprintf (f, "Slope\t") ; if (flags->intercept==l) fprintf (f, "Intercept\t") ;

if (flags->R==l) fprintf (f, if (flags->region_reference_flag==1) stat_flags_labels (&flags->region_reference, f); if (flags->spot_reference_flag==1) stat_flags_labels (&flags->spot_reference, f) ; if (flags->background_reference_flag==1) { stat_flags_labels (&flags->background_reference, f) ; if (flags->region_common_flag==1) stat_flags_labels (&flags->region_common, f) ; } if (flags->spot_common_flag==1)

statflagslabels (&flags->spotcommon, f) ; } if (flags->background_common_flag==1) statflagslabels (&flags->backgroundcommon, f) ; if ( (flags->ratiocommonflag==l) && (!is_ref) ) { stat_flags_labels (&flags->ratiocommon, f) ; if (p->gene_id_column_headings!=NULL) { fprintf (f, "%s", p->gene_id_column_headings); else fprintf (f, "\n"); /* Exclude missing */ if (p [0]. include missing==0) for (pr=0 ; pr<p [0]. pins_per_column ; pr++) for (pc=0 ; pc<p [0]. pins per row ; pc++) for (sr=0 ; sr<p [0]. spotspercolumn ; sr++) for (sc=0 ; sc<p [0]. spots_per_row ; sc++) i=get_spot_number (pr, pc, sr, sc, p) ; if (j [i] ! =-l)

if ((boxes [j [i]]. box_type==IN_GRID) && ((p[0].spot_type[i]=REGULAR) ## (p [0]. spot_type[i]==POSITIVE) # (p [0]. spot_type [i] ==NEGATIVE))) print_output_data_line (pr, pc, sr, sc, &boxes [j [i]], p, flags, f, is_ref) ; /* Include all spots in order */ if (p [0]. include missing==1) for (pr=0 ; pr<p [0]. pinspercolumn ; pr++) for (pc=0 ; pc<p [0]. pinsperrow ; pc++) for (sr=0 ; sr<p [0]. spots_per_column ; sr++) for (sc=0 ; sc<p [0]. spots per row ; sc++) {i=getspotnumber (pr, pc, sr, sc, p) ; if (j[i] !=-1) if (boxes [j [i]]. boxtype==INGRID) print output data-line (pr, pc, sr, sc, &boxes [j [i]], p, flags, f, is_ref) ; /* Separate output into regions by type */ if (p [0]. include missing==2) for (current-spot type=0 ; currentspottype<p->spottypes. numberoftypes ; currentspottype++)

for (pr=0 ; pr<p [0]. pinspercolumn ; pr++) for (pc=0 ; pc<p [0]. pinsperrow ; pc++) for (sr=0 ; sr<p [0]. spots-per column ; sr++) for (sc=0 ; sc<p [0]. spotsperrow ; sc++) {i=getspotnumber (pr, pc, sr, sc, p) ; if (j [i] ! =-l) if ((p[0].spot_type[i]==current_spot_type) && (boxes [j [i]]. boxtype==INGRID)) print output data-line (pr, pc, sr, sc, &boxes [j [i]], p, flags, f, is_ref) ; /* Lets calculate subgrid averages for dilution series type work */ fprintf (f,"\nSubgrid Averages\n") ; sgb= (struct box *) malloc (sizeof (struct box) *p [0]. pinspercolumn*p [0]. pinsperrow) ; if (sgb==NULL) {printf ("Failed malloc for sgb in write_data... \n") ; exit (-l) ; fprintf (f, "SubRow\tSubCol\tRegAvg\tRegArea\tRegSDV\tSpotAvg\tSpot Area\tSpotSDV\tBGAvg\tBGArea\tBGSDV\n") ;

for (pr=0 ; pr<p [0]. pins per column ; pr++) for (pc=0 ; pc<p [0]. pinsperrow ; pc++) {pn=pr*p [0]. pins_per_row+pc ; sgb [pn]. spot. average=0. 0 ; sgb [pn]. spot. area=0 ; sgb [pn]. spot. std dev=0. 0 ; sgb [pn]. box. average=0. 0 ; sgb [pn]. box. area=0 ; sgb [pn]. box. std dev=0. 0 ; sgb [pn]. background. average=0. 0 ; sgb [pn]. background. area=0 ; sgb [pn]. background. std dev=0. 0 ; for (sr=0 ; sr<p [0]. spotspercolumn ; sr++) for (sc=0 ; sc<p [0]. spots-per row ; sc++) {i=getspotnumber (pr, pc, sr, sc, p) ; sgb [pn]. spot. area+=boxes [j [i]]. spot. area ; sgb [pn]. spot. average+=boxes [j [i]]. spot. area*boxes [j [i]] . spot. average ; sgb [pn]. spot. stddev+=boxes [j [i]]. spot. area*boxes [j [i]] . spot. average* boxes [j [i]]. spot. area*boxes [j [i]]. spot. average ; sgb [pn]. box. area+=boxes [j [i]]. box. area ;

sgb [pn]. box. average+=boxes [j [i]]. box. area*boxes [j [i]]. b ox. average ; sgb [pn]. box. stddev+=boxes [j [i]]. box. area*boxes [j [i]]. b ox. average* boxes [j [i]]. box. area*boxes [j [i]]. box. average ; sgb [pn]. background. area+=boxes [j [i]]. background. area ; sgb [pn]. background. average+=boxes [j [i]]. background. area *boxes [j [i]]. background. average ; sgb [pn]. background. stddev+=boxes [j [i]]. background. area *boxes [j [i]]. background. average* boxes [j [i]]. background. area*boxes [j [i]]. background. aver age ; sgb [pn]. spot. area= (int) ( ( (double) sgb [pn]. spot. area)/ ( (double) p [0]. spots_per_row)/((double) p [0]. spots_per-column)) ; sgb [pn]. box. area= (int) ( ( (double) sgb [pn]. box. area)/ ( (double) p [0]. spots_per_row)/((double) p [0]. spots_per_column)) ;

sgb [pn]. background. area= (int) ( ( (double) sgb [pn]. background. area)/ ( (double) p [0]. spots_per_row)/((double) p[0].spots_per-column)) ; sgb [pn]. spot. average=sgb [pn]. spot. average/ ( (double) p [0]. spots_per_row)/((double) p [0]. spotspercolumn) ; sgb [pn]. box. average=sgb [pn]. box. average/ ( (double) p [0]. spots_per_row)/((double) p [0]. spotspercolumn) ; sgb [pn]. background. average=sgb [pn]. background. aver age/ ( (double) p [0]. spots_per_row)/((double) p [0]. spots_per_column) ; sgb [pn]. spot. stddev=sgb [pn]. spot. std_dev/((double) p [0]. spots_per_row)/((double) p [0]. spots per column) ; sgb [pn]. box. stddev=sgb [pn]. box. std_dev/((double) p [0]. spots_per_row)/((double) p [0]. spots-per column) ; sgb [pn]. background. stddev=sgb [pn]. background. std dev/ ( (double) p [0]. spots_per_row)/((double) p [0]. spots per column) ; sgb [pn]. spot. stddev=sqrt (sgb [pn]. spot. std dev-sgb [pn]. spot. average*sgb [pn]. spot. average) ; sgb [pn]. box. stddev=sqrt (sgb [pn]. box. stddev-sgb [p n]. box. average*sgb [pn]. box. average) ;

sgb [pn]. background. stddev=sqrt (sgb [pn]. background . stddev-sgb [pn]. background. average*sgb [pn]. background. aver sgb [pn]. spot. average=sgb [pn]. spot. average/sgb [pn]. spot. area ; sgb [pn]. box. average=sgb [pn]. box. average/sgb [pn]. box. are a ; sgb [pn]. background. average=sgb [pn]. background. aver age/sgb [pn]. background. area ; sgb [pn]. spot. stddev=sgb [pn]. spot. stddev/sgb [pn]. spot. area ; sgb [pn]. box. stddev=sgb [pn]. box. stddev/sgb [pn]. box. are a ; sgb [pn]. background. stddev=sgb [pn]. background. stddev/s gb [pn]. background. area ; fprintf (f, "%6i\t", pr+1) ; fprintf (f,"W6i\t", pc+l) ; fprintf (f, "%8.3f\t", sgb[pn]. box. average) ; fprintf (f, "%6i\t", sgb[pn]. box. area) ; fprintf (f,"%8. 3f\t", sgb [pn]. box. std-dev) ; fprintf (f,"%8. 3f\t", sgb [pn]. spot. average) ; fprintf (f, "%6i\t", sgb [pn]. spot. area) ;

fprintf (f, "%8.3f\t", sgb [pn]. spot. std-dev) ; fprintf (f,"p8. 3f\t", sgb [pn]. background. average) ; fprintf (f, "%6i\t", sgb [pn]. background. area) ; fprintf (f,"o8. 3f\t", sgb [pn]. background. std-dev) ; fprintf (f,"\t") ; fprintf (f,"t8. 3f\t", sgb [pn]. box. average-sgb [pn]. background. average) ; fprintf (f, "%8. 3f\t", sgb [pn]. spot. average-sgb [pn]. background. average) ; fprintf (f,"\n") ; fprintf (f,"\nSubgrid Positions and Vectors\n") ; fprintf (f, "SubRow\tSubCol\tRowOffset\tColOffset\tax\tay\ta-Theta\ tbx\tby\tb-Theta\n") ; for (pr=0 ; pr<p [0]. pins_per_column ; pr++) for (pc=0 ; pc<p [0]. pins_per_row ; pc++) {pn=pr*p [0]. pinsperrow+pc ; if (p [0]. axp ! =NULL) fprintf (f, "%6i\t%6i\t%6i\t%6i\t%+8.3f\t%+8.3f\t%+8.3f\t%+8.3f\t%+ 8. 3f\t%+8. 3f\n", pr+1, pc+1, p [0]. row_offsets [pn]

p [0]. columnoffsets [pn], p [0]. axp [pn], p [0]. ayp [pn], 180. 0/3. 141592534*atan (p [0]. ayp [pn]/p [0]. axp [pn]), p [0]. bxp [pn], p [0]. byp [pn], 180. 0/3. 141592534*atan (p [0]. bxp [pn]/p [0]. byp. [pn])) ; else fprintf (f, "%6i\t%6i\t%6i\t%6i\t%+8.3f\t%+8.3f\t%+8.3f\t%+8.3f\t%+ 8. 3f\t%+8. 3f\n", pr+l, pc+1, p [0]. rowoffsets [pn], p [0]. columnoffsets [pn], p [0]. ax, p [0]. ay, 180. 0/MPI*atan (p [0]. ay/p [0]. ax), p [0]. bx, p [0]. by, 180. 0/MPI*atan (p [0]. bx/p [0]. by)) ; free (j) ; free (fname) ; fclose (f) ; void printoutputdataline (int pr, int pc, int sr, int sc, struct box *b, struct printer *p, struct output_data * flags, FILE *f, int is_ref) {int i, pn ;

double x, y ; i=get_spot-number (pr, pc, sr, sc, p) ; if (flags->pin_row==1) fprintf (f, "%6i\t", pr+1) ; if (flags->pin_column==1) fprintf (f, "%6i\t", pc+1) ; if (flags->spot row==l) fprintf (f, "%6i\t", sr+1) ; if (flags->spot column==l) fprintf (f, "%6i\t", sc+1) ; if (flags->spot_number==10 fprintf (f, "%6i\t", i) ; if (flags->spot_type==l) fprintf (f, "%s\t", p->spot_types.type_name [p->spot_type[i]]) ; get xyfromspotandpin ( ( (double) pc), ( (double) pr), ( (double) sc), ( (double) sr), p, &x, &y) ; pn=get_pin_number_from_spot_number (i, p) ; x=x+p [0]. columnoffsets [pn] ; y=y+p [0]. row_offsets[pn] ; if (flags->grid. row==l) fprintf (f, "%8.3f\t", ((double) y)) ; if (flags->grid_column==1) fprintf (f, "W8. 3f\t", ( (double) x)) ; if (flags->region_flag==1) {

if (flags->boxrow==l) fprintf (f, "%6i\t", b->box_row) ; if (flags->box_column==1) fprintf (f, "%6i\t", b->box_column) ; if (flags->box_dist_to_grid==1) fprintf (f, "%8. 3f\t", ( (double) sqrt ( (((double) b->box_row) - y) * ( ( (double) b->boxrow)-y) + ( ( (double) b->boxcolumn)-x) * ( ( (double) b->boxcolumn)-x)))) ; stat_flags_values (&flags->region,&b->box, f) ; if (flags->spot_flag==l) if (flags->spot_ybar==l) fprintf (f, "%6i\t", ((int) b->spot_ybar)) ; if (flags->spot xbar==l) fprintf (f, "%6i\t", ((int) b->spot_xbar)) ; if (flags->spot_dist_to_grid==1) fprintf (f, "%8. 3f\t", ( (double) sqrt ( (((double) b->spot_ybar) - y) *

( ( (double) b->spotybar)-y) + ( ( (double) b->spotxbar)-x) * ( ( (double) b->spotxbar)-x)))) ; statflagsvalues (&flags->spot, &b->spot, f) ; if (flags->spot perimeter==l) fprintf (f, "%6i\t", ((int) b->spot_perimeter)) ; if (flags->spot width==l) fprintf (f, "%6i\t", ((int) b->spot_width)) ; if (flags->spot height==l) fprintf (f, "%6i\t", ((int0 b->spot_height)) ; if (flags->spot_rbar==1) fprintf (f, "%8.3f\t", b->spot_rbar) ; if (flags->spot_rmin==1) fprintf (f, "%8. 3f\t", b->spot_rmin) ; if (flags->spot_rmax==1) fprintf (f, "%8.3f\t", b->spot_rmax) ; if (flags->background_flag==1) stat)_flags_values (&flags->background,&b->background, f) ; }

if ( ! is ref) { if (flags->regionwrtreferenceflag==l) <BR> <BR> <BR> <BR> <BR> statflagsvalues (&flags->regionwrtreference, &b->wrt reference->region, f) ; } if (flags->spot_wrt_reference_flag==1) statflagsvalues (&flags->spotwrtreference, &b->w rtreference->spot, f) ; if (flags->background_wrt_reference_flag==10 stat_flags_values (&flags->background_wrt_reference , &b->wrtreference->background, f) ; if (flags->ratio_wrt_reference_flag==1) { statflagsdvalues (&flags->ratiowrtreference, &b- >wrtreference->ratio, f) ; if (flags->rowshift==l) fprintf (f, "%10.5f\t", (b->row_shift)) ; if (flags->col_shift==1) fprintf (f, "%10. 5f\t", (b->colshift)) ;

if (flags->slope==l) fprintf (f, "%8.3f\t", b->slope) ; if (flags->intercept==l) fprintf (f, "o8. 3f\t", b->intercept) ; if (flags->R==l) fprintf (f, "% 8. 3f\t", b->R) ; if (flags->regionreferenceflag==l) stat-flags_values (&flags->region_reference,&b->ref erence->region, f) ; if (flags->spot_reference_flag==10 stat flags values (&flags->spotreference, &b->refer ence->spot, f) ; if (flags->background_reference_flag==1) { stat flags values (&flags->background reference, &b- >reference->background, f) ;

if (flags->region common-flag==l) <BR> <BR> statflagsvalues (&flags->regioncommon, &b->common->reg ion, f) ; if (flags->spot_common_flag==1) stat-flags values (&flags->spot common, &b->common->spot, f) ; } if (flags->backgroundcommonflag==l) { statflagsvalues (&flags->backgroundcommon, &b->common- >background, f) ; if ( (flags->ratio_common_flag==1) && (!is_ref)) stat_flags_dvalues (&flags->ratio_common, &b->common->rat io, f) ; }

if (p->gene_id ! =NULL) { if (p->gene_id[i] ! =NULL) fprintf (f, "%s", p->gene_id[i]) ; else fprintf (f,"\n") ; else fprintf (f,"\n") ; /*fprintf (f,"\n") ; */ /* The following function is for Mary Trounstine to Lock Down Output Data */ void set_output_flags_QC (struct output data * flags) flags->pin_row=1 ; flags->pin_column=1 ; flags->spot_row=l ; flags->spot_column=1 ; flags->spotnumber=l ; flags->spot_type=1 ; flags->ratio_common-flag=0 ; flags->gridrow=0 ; flags->gridcolumn=0 ; flags->region_flag=l ;

flags->boxrow=0 ; flags->boxcolumn=0 ; flags->box_dist-to_grid=0 ; flags->region. average=l ; flags->region. std_dev=0 ; flags->region. median=0 ; flags->region. average one-sd=0 ; flags->region. average_two_sd=0 ; flags->region. area=l ; flags->region. areaonesd=0 ; flags->region. area two-sd=0 ; flags->region. area zero=0 ; flags->region. area_saturated=1 ; flags->region. min=0 ; flags->region. max=0 ; flags->spot_flag=l ; flags->spotybar=0 ; flags->spot_xbar=0 ; flags->spot_dist_to_grid=0 ; flags->spot. average=l ; flags->spot. std-dev=0 ; flags->spot. median=0 ; flags->spot. average_one_sd=0 ; flags->spot. average two sd=0 ; flags->spot. area=l ; flags->spot. areaonesd=0 ; flags->spot. areatwosd=0 ;

flags->spot. area zero=0 ; flags->spot. areasaturated=l ; flags->spot. min=0 ; flags->spot. max=0 ; flags->slope=0 ; flags->intercept=0 ; flags->R=0 ; flags->spot_perimeter=l ; flags->spotwidth=0 ; flags->spot_height=0 ; flags->spot_rbar=1 ; flags->spot_rmin=0 ; flags->spot_rmax=0 ; flags->background_flag=l ; flags-background. average=l ; flags->background. std_dev=1 ; flags->background. median=0 ; flags-background. average_one_sd=0 ; flags->background. average_two_sd=0 ; flags->background. area=l ; flags->background. area one sd=0 ; flags->background. area two sd=0 ; flags->background. area zero=0 ; flags->background. area_saturated=1 ; flags->background. min=0 ; flags->background. max=0 ;

output image. c #include"defs. h" void output_image (struct image data * image, struct output_image_params * oparams) printf ("writing output image file (s)... \n") ; if (oparams->tiff_zip_flag==l) write_tiff_zip (image, oparams [0]. output_path) ; if (oparams->tiff_jpg_flag==10 write_tiff_jpeg (image, oparams->jpg_quality, oparams [0]. outputpath) ; if (oparams->jpg_flag==1) write_jpeg (image, oparams->jpgquality, oparams [0]. output_path) ; if (oparams->ppm_flag==10 write_ppm (image, oparams [0]. output path) ; } void output_integrated_image (struct image data * image, struct output_image_params * oparams) { char *fname ; int i ; struct image data int-image ;

int pixel ; Integrated max ; printf ("writing output image file with integrated data... \n") ; /* put an extension on the output filename */ for (i= (strlen (image [0]. filename)-l) ; (i> (-l)) && (image [0]. file_name [i] ! =SLASHCHAR) && (image [0]. file_name [i] ! =':') ; i--) ; i++ ; fname= (char *) malloc (sizeof (char) * (10+strlen (oparams [0]. output_path) + strlen (image [0]. filename)-i)) ; if (fname==NULL) {printf ("Failed malloc for filename memory in outputintegratedimage... \n") ; exit (-l) ; } strcpy (fname, oparams [0]. output-path) ; if (fname [strlen (fname)-l] ! =SLASHCHAR) strcat (fname, SLASHSTRING) ; strcat (fname,"int") ; strcat (fname, &image [0]. filename [i]) ;

int_image. filename=fname ; int-image. data= (unsigned short int *) malloc (sizeof (unsigned short int) *image->width*image->height) ; if (int-image. data==NULL) {printf ("Failed malloc in output_integrated... \n") ;' # return ; int_image. width=image->width ; int-image. height=image->height ; max=0. 0 ; for (pixel=0 ; pixel< (image->width*image->height) ; pixel++) if (max<image->integrateddata [pixel]) max=image->integra teddata [pixel] ; for (pixel=0;pixel< (image->width*image->height) ; pixel++) int_image. data [pixel] = (unsigned short int) (MAX-INTENSITY* (image->integrateddata [pixel]/max)) if (oparams->tiff_zip_flag==l) writetiffzip (&intimage, oparams [0]. output_path) ; if (oparams->tiff_jpg_flag==1) write_tiff_jpeg (&int_image, oparams->jpg_quality, oparams [0]. output path) ; if (oparams->jpg_flag==l)

write_jpeg (&int_image, oparams->jpg_quality, oparams [0]. output_path) ; if (oparams->ppm_flag==10 write_ppm (&int_image, oparams [0]. output_path) ; free (fname) ; free (int_image. data) ; overlap. c #include"defs. h" void set pixel attributes (char * pixel, char additional-attributes) {char hold ; if (additionalattributes==EMPTYPIXEL) {pixel [0] =0 ; return ; else { hold=pixel[0] # additional_attributes ; pixel [0] =hold ; } return ;

void unsetpixelattributes (char * pixel, char attributes) char hold ; hold = pixel [0] &attributes ; pixel [0] = pixel [0] ^hold ; return ; /* This function returns zero if the pixel shares none of the attributes of the test_attribte argument. If the pixel contains at least one of the attributes in test-attribute but is still not an exact match,-1 is returned. If an exact match is found, the function returns 1.

*/ int test pixel-attributes (char pixel, char test_attributes) if (testattributes==pixel) return (l) ;

if ( (pixel & test_attributes) !=0) return (-l) ; return (0) ; void createoverlapimage (struct overlap *oimage, struct image data *image, struct spot_finding_params *sfparams, struct background_params *bgparams, struct integration_params *iparams, struct printer * pparams) { int i, il pixel, sn, n. um pixels, outer-radius, * pixelpositions, * perimeter_pixels ; struct. background_params dummy_bg ; oimage->width=image->width ; oimage->height=image->height ; if (oimage->image ! =NULL)

free (oimage->image) ; oimage->image= (char *) malloc (oimage->width*oimage->height) ; if (oimage->image==NULL) {printf ("Failed malloc for oimage->image in createoverlapimage... \n") ; exit (-l) ; for (i=0 ; i< (oimage->width*oimage->height) ; i++) set pixel attributes (&oimage->image [i], EMPTY PIXEL) ; /* Spot */ for (i=0 ; i<image->numboxes ; i++) if (image->boxes [i]. boxtype==INGRID) {sn=getspotnumber (image->boxes [i]. pinrow, image->boxes [i]. pin_column, image->boxes [i]. spot_row, image->boxes [i]. spot-column, pparams) ; if ((pparams->spot_type[sn]==REGULAR) (pparams->spot_type [sn] ==POSITIVE)<BR> (pparams->spot_type [sn] ==NEGATIVE)) {if (image->boxes [i]. spot. pixel_positions==NULL)

get_largest_spot_pixels (image, &image->boxes [i], sfparams) ; for (j=0 ; j<image->boxes [i]. spot. area ; j++) pixel=image->boxes [i]. spot. pixelpositions [j] ; setpixelattributes (&oimage->image [pixel], SPOT_PIXEL) ; } if (image->boxes [i]. spot. pixel_positions==NULL) free (image->boxes [i]. spot. pixel-positions) ; /* Spot perimeter */ for (i=0 ; i<image->numboxes ; i++) if (image->boxes [i]. boxtype==INGRID) {sn=getspotnumber (image->boxes [i]. pinrow, image->boxes [i]. pin_column, image->boxes [i]. spotrow, image->boxes [i]. spot-column, pparams) ; if ( ((pparams->spot_type[sn]==REGULAR) ## (pparams->spot_type [sn] ==POSITIVE) (pparams->spot_type[sn]==NEGATIVE))&& (image->boxes [i]. spotperimeter>0)) {

perimeter_pixels= (int *) malloc (sizeof (int) *image->boxes [i]. spot_perimeter) ; if (perimeter_pixels= =NULL) { printf ("Failed malloc for perimeter pixels in create overlap-image... perimeter = %i\n", image->boxes [i]. spot_perimeter) ; exit (-l) ; get_largest_spot_perimeter(perimeter_pixels, image, &image->boxes[i], sfparams) ; for (j=0 ; j<image->boxes [i]. spot_perimeter ; j++) { pixel=perimeter_pixels [j] ; set_pixel_attributes (&oimage->image [pixel], SPOT PERIMETER PIXEL) ; free (perimeter pixels) ; /* Background */ if (bgparams->mask_flag==l) {pixel_positions= (int *) malloc (bgparams->maskwidth*bgparams->maskwidth*sizeof (int)) ;

if (pixel_positions==NULL) {printf ("Failed malloc for pixel positions in create overlap-image... \n") ; exit (-l) ; else {outerradius=bgparams->backgroundradius ; pixel_positions= (int *) malloc ((2*outer_radius+1) * (2*outer radius+1) *sizeof (int )) ; if (pixel_positions==NULL) {printf ("Failed malloc for pixel positions in create_overlap_image...\n") ; exit (-l) ; for (i=0 ; i<image [0]. numboxes ; i++) &num ifdef WET DOT if (image [0]. boxes [i]. boxtype==NOTINGRID) #else if (image [0]. boxes [i].box_type==IN_GRID) #endif {sn=getspotnumber (image->boxes [i]. pinrow, image->boxes [i]. pin_column, image->boxes [i]. spot row, image->boxes [i]. spot column,

pparams) ; #ifdef WET DOT if (pparams->spot_type [sn] ! =EMPTY) #else if ((pparams->spot_type[sn]==REGULAR) (pparams->spot_type[sn]==POSITIVE) (pparams->spot_type [sn] ==NEGATIVE)) #endif get background pixels (image, bgparams, & : image [Ol. boxe's [i], &num_pixels, pixel_positions) ; for (j=0 ; j<numpixels ; j++) set_pixel-attributes (&oimage->image [pixelpositions [j]] BACKGROUND-PIXEL) ; free (pixel-positions) ; /* Region */ if (iparams->mask_flag==10 pixel_positions= (int *) malloc (iparams->mask_width*iparams->mask_width*sizeof (i nt)) ; if (pixel_positions==NULL) {printf ("Failed malloc for pixel_positions in create_overlap_image... \n") ; exit (-l) ;

else {outerradius= iparams->integrationradius ; pixel-positions= (int *) malloc ((2*outer_radius+1) * (2*outer_radius+1) *sizeof (int if (pixel_positions==NULL) {printf ("Failed malloc for pixel_positions in create overlap-image... \n") ; exit (-l) ; for (i=0 ; i<image [0]. numboxes ; i++) if (image [0]. boxes [i]. boxtype==INGRID) sn=get_spot_number (image->boxes[i].pin_row, image->boxes [i]. pin_column, image->boxes [i]. spot_ro0w, image->boxes [i]. spot column, pparams) ; if ((pparams->spot_type[sn]==REGULAR) (pparams->spot_type[sn]==POSITIVE) (pparams->spot_type [sn] ==NEGATIVE)) {get_region_pixels (image, iparams, image [0]. boxes[i].box_row, image [0]. boxes [i]. boxcolumn, &numpixels, pixel positions) ;

for (j=0 ; j<numpixels ; j++) setpixelattributes (&oimage->image [pixel_positions [j]] REGION-PIXEL) ; /* Region Pixel*/ dummy_bg.mask_width=iparams->mask_width ; dummy_bg. mask=iparams->perimeter mask ; dummy_bg.mask_flag=iparams->mask_flag dummy_bg. mask-file-flag=iparams->mask-file-flag ; dummy_bg.square_flag=iparams->square_flag ; dummy_bg.circle_flag=iparams->circle_flag ; dummy_bg.background_width=iparams->integration_width ; dummybg. backgroundheight=iparams->integrationheight ; dummy_bg.background_radius=iparams->integration_radius ; dummy_bg.background_frame_width=1 ; for (i=0 ; i<image [0]. numboxes ; i++) if (image [0]. boxes [i]. boxtype==INGRID) { sn=get_spot_number (image->boxes [i]. pin_row, image->boxes [i]. pin-column, image->boxes [i]. spot_row, image->boxes [i]. spot_column, pparams) ;

#ifdef WET DOT if (pparams->spot_type [sn] ==EMPTY) #else if ((pparmas->spot_type [sn] ==REGULAR) (pparams->spot_type [sn] ==POSITIVE) (pparams->spot_type [sn] ==NEGATIVE)) #endif {getbackgroundpixels (image, &dummy_bg, &image [0]. boxes [i], &numpixels, pixelpositions) ; for (j=0 ; j<num pixels ; j++) set-pixel_attributes (&oimage->image [pixel_positions [j]] , REGION_PERIMETER_PIXEL) ; free (pixel positions) ; /*write_color_overlap_ppm (image, oimage,".") ; exit (-l) ; */ } void add_saturation_to_overlap (struct overlap * oimage, struct image-data * image) {int i ;

if ( (image->width==oimage->width) && (image->height==oimage->height) && (oimage->image ! =NULL)) for (i=0 ; i<oimage->width*oimage->height ; i++) if (image->data [i] ==MAXINTENSITY) set-pixel attributes (&oimage->image [i], SATURATED PIXEL) ; void remove-attributes (struct overlap * oimage, char attributes) { int i ; if (oimage->image ! =NULL) for (i=0 ; i<oimage->width*oimage->height ; i++) unsetpixelattributes (&oimage->image [i], attributes) ; ppm.c #include"defs. h" int write ppm (struct image data *our image, char *output-path) {long int i, N ;

FILE *f ; char *fname ; /*change the path and add the extension for the output file*/ fname = get_new_file_name(our_image[0].file_name, output_path,". ppm") ; printf ("%s\n", fname); f=fopen (fname"w+b") ; if (f==NULL) {printf ("Failed to open file %s in write_ppm... \n", fname) ; return (-l) ; fprintf (f,"P5\n&num CREATOR : WSPOT\n%i %i\n255\n", out-image [0]. width, our-image [0]. height) ; N=ourimage [0]. width*ourimage [0]. height ; for (i=0 ; i<N ; i++) fprintf (f,"oc", (unsigned char) (255- out-image [0]. data [i]/256)) ; fprintf (f,"\n") ; fclose (f) ; free (fname) ;

return (0) ; int writecoloroverlapppm (struct image data * our-image, struct overlap * oimage, char * output-path) .{ long int. i, N ; int set ; FILE *f ; char *fname ; /*change the path and add the extension for the output file*/ fname = <BR> getnewfilename (ourimage [0]. filename, outputpath,". ppm"); printf ("%s\n", fname) ; f=fopen (fname,"w+b") ; if (f==NULL) {printf ("Failed to open file os in write ppm... \n", fname) ; return (-l) ;

fprintf (f, "P6\n# CREATOR : SWPOT\n%i %i\n255\n", out-image [0]. width, our-image [0]. height) ; N=ourimage [0]. width*ourimage [0]. height ; for (i=0 ; i<N ; i++) {if (oimage->image [i] ==0) {fprintf (f,"ococ%c", (unsigned char) (255- our-image [0]. data [i]/256), (unsigned char) (255- ourimage [0]. data [i]/256), (unsigned char) (255- our-image [0]. data [i]/256)) ; } else {set=0 ; /* Write background pixels*/ if ((set==0) && (test pixel attributes (oimage->image [i], BACKGROUND PIXEL) ! =0) && (test_pixel_attributes (oimage->image [i], SPOT PIXEL) ==0)) { fprintf (f, "%c%c%c", (unsigned char) (255 our_image [0]. data [i]/256), (unsigned char) 0, (unsigned char) 0) ; set=l ;

/* Write spot pixels */ if ((set==0) && (testpixelattributes (oimage->image [i], SPOT PIXEL) ! =0)) if (testpixelattributes (oimage->image [i], SPOT_PERIMETER_PIXEL) ! =0) fprintf (f, "%c%c%c", (unsigned char) 0, (unsigned char) 0, (unsigned char) (255- ourimage [0]. data [i]/256)) ; else fprintf (f, "%c%c%c", (unsigned char) (255 out-image [0]. data [i]/256), (unsigned char) (255- ourimage [0]. data [i]/256), (unsigned char) 0) ; set=l ; } /* Write region pixels */ if ((set==0) && (test_pixel_attributes (oimage->image [i], REGION_PERIMETER_PIXEL) ! =0))

fprintf (f, "%c%c%c", (unsigned char) 0, (unsigned char) (255- ourimage [0]. data [i]/256), (unsigned char) 0) ; set=l ; if (set==0) fprintf (f, "%c%c%c", (unsigned char) (255- out-image [0]. data [i]/256), (unsigned char) (255- our_image [0]. data [i]/256), (unsigned char) (255- our-image [0]. data [i]/256)) ; fprintf (f,"\n") ; fclose (f) ; free (fname) ; return (0) ; int writeppmascii (struct image_data *our_image char *output-path) { long int i, N ;

FILE *f ; char *fname ; /*change the path and add the extension for the output file*/ fname = <BR> <BR> <BR> <BR> <BR> getnewfilename (ourimage [0]. filename, outputpath,". ppm") ; ) printf ("s\n", fname) ; f=fopen (fname,"w") ; if (f==NULL) {printf ("Failed to open file %s in writeppmascii... \n", fname) ; return (-l) ; fprintf (f,"P2\n&num CREATOR : WSPOT\n%i %i\n%i\n", our-image [0]. width, our-image [0]. height, MAX-INTENSITY) ; N=our-image [0]. width*our_image [0]. height ; for (i=0 ; i<N ; i++) fprintf (f,"ou", our-image [0]. data [i]) ; fprintf (f, "\n"); fclose (f) ; free (fname); return (0) ;

int writemultiimageppm (struct image data *our_image [], int numimages, char *output_path) {long int i, j, N ; FILE *f ; char *fname ; if (numimages>3) { printf ("writemultiimageppm : do not know how to write multi-image ppm file with oui images\n", numimages) ; return (l) ; /*change the path and add the extension for the output file*/ fname = <BR> getnewfilename (ourimage [0]->filename, outputpath," multi. ppm") ; printf ("% s\n", fname) ; f=fopen (fname, "w+b") ; if (f==NULL) {printf ("Failed to open file %s in write_multi_image_ppm...\n", fname) ; return (-l) ;

fprintf (f,"P6\n&num CREATOR : SPOT\n%i %i\n255\n", our-image [0]->width, out-image [0]->height) ; N=our_image [0]->width*ourimage [0]->height ; for (i=0 ; i<N ; i++) for (j=0 ; j<numimages ; j++) fprintf (f, "%c", (unsigned char) (our-image [j3->data [i]/256)) ; for (j=numimages ; j<3 ; j++) fprintf (f, "%c", (unsigned char) 0) ; fprintf (f,"\n") ; fclose (f) ; free (fname) ; return (0) ; quality. c #include"defs. h" double quality (struct box * s, struct quality_params * qparams)

double value, rmin, rmax ; if (s->spot_rmin<1. 0) { rmin = 0. 5 ; else rmin. = s->spot_rmin ; if (s->spot_rmax<1. 0) rmax = 1. 0 ; else rmax = s->spot_rmax ; } value = qparams->intensity*s->box. average -qparams->background*s->background. average +qparams->area*s->spot. area -qparams->roundness* ((rmax/rmin)-1. 0) -qparams->distance_spot_to_grid*s->spot_distance_from_ g rid

-qparams->distance_spot_to box*sqrt (pow ((double) s->box_ row-s->spotybar, 2. 0) +pow ((double)s->box_colum-s->spot xbar, 2. 0)) ; return (value) ; void improve_quality (struct image-data * image, struct parameters * all_params) {int i, row, col, numspotscentered ; struct box centered-box ; double x, y ; /* copies of passed variables */ struct box * s ; int numboxes ; /* copy over passed variables */ s=image->boxes ; numboxes=image->numboxes ; num_spots_centered = 0 ; for (i=0 ; i<numboxes ; i++) { if (s [i]. spotdistancefromgrid>0. 0) {

get xyfromspotandpin ( (double) s [i]. pin-column, (double) s [i]. pin row, (double) s [i]. spot column, (double) s [i]. spot_row, &all_params->printer_info, &x, &y) ; row. = (int) (y+0. 5) ; col = (int) (x+0. 5) ; create-box (image, row, col, &all_params->integration, &all_params->integration_small, &all_params->background ¢eredbox) ; get_largest_spot_statistics (image, ¢eredbox, &al_params->crop_image_data.spot_params) ; if (quality (¢ered_box,&all_params->quality) >quality ( &s [i], &all_params->quality)) printf ("%i %i\n", s [i]. spot_row+1, s [i]. spot_column+1) ; printf ("%If %If\n\n", quality (&s [i], &all_params->quality), quality (&c entered box, &all_params->quality)) ; s [i]. boxtype=NOTINGRID ;

if (quality (¢ered-box, &all_params->quality) >quality ( &s [i], &all_params->quality)) printf ("% i %i\n", s [i]. spot_row+1, s [i]. spot column+1) ; printf ("% lf %If\n\n", quality (&s [i], &all_params->quality), quality (&c enteredbox, &allparams->quality)) ; s [i]. box_type=NOT_IN-GRID; num_spots_centered++ ; } printf ("centered % i spots in % i boxes in improve_quality\n", num-spots_centered, num_boxes) ; read parameters. c #include"defs. h" #define PARAMETER ENTRIES 312 int check_on_off_parameter (char * parameter, char * value, char * check, int * flag)

char ps [getpagesize ()] ; strncpy (ps, parameter, strlen (parameter)-l) ; ps [strlen (parameter)-11=0 ; if (strcmp (parameter, check) ==0) { if (strcmp (value,"on\n") ==0) { *flag=l ; printf ("%s set to on\n", ps) ; return (l) ; if (strcmp (value,"off\n") ==0) { *flag=0 ; printf ("% s set to off\n", ps) ; return (l) ; return (0) ; int read-statistics parameter (struct statistics-flags * flags, char * parameter, char * value) /*average*/

if (check_on_off_parameter (parameter, value, "average\n", &flags->average)) return (0) ; /*std dev*/ if (check on off parameter (parameter, value, "std_dev\n", & flags->stddev)) return (. 1) ; /*median*/ if (check on off parameter (parameter, value,"median\n", &f lags->median)) return (2) ; /*average_one_sd*/ if (checkonoffparameter (parameter, value,"average_one_ sd\n", &flags->averageonesd)) return (3) ; /*average_two_sd*/ if (check-on off parameter (parameter, value,"average_two_ sd\n", &flags->average_twosd))

return (4) ; /*area*/ if (check on off-parameter (parameter, value,"area\n", &fla gs->area)) return (5) ; /*area_one_sd*/ if (check_on_off_parameter (parameter, value, "area_one_sd\ n", &flags->areaonesd)) return (6) ; /*area_two_sd*/ if (check_on_off_parameter(parmater, value, "area_two_sd\ n", &flags->areatwosd)) return (7) ; /*area_zero*/ if (check on off parameter (parameter, value, "area_zero\n" , &flags->areazero)) return (8) ; /*area-saturated*/

if (check-on-off parameter (parameter, value,"area-saturat ed\n", &flags->area_saturated)) return (9) ; /*min*/ if (check on off parameter (parameter, value,"min\n", &flag s->min)) return (10) ; /*max*/ if (check on off parameter (parameter, value,"max\n", &flag s->max)) return (ll) ; printf ("\n&num ***Warning, did not find a valid statistics parameter in read statistics parameter ! ***\n") ; printf ("% s\n", parameter) ; return (-l) ; char * check parameter (char * parameter, char * check)

if ( (strstr (parameter, check) ==parameter) && (strlen (parameter) >strlen (check))) { printf ("% s", check) ; return (¶meter [strlen (check)]) ; return (NULL) ; void get_output_data_param (char * parameter, char * value, struct output data * odata, int * flag) char * stat_ptr ; int temp, set value ;

if (check on off parameter (parameter, value, "region\n",<BR> &odata->regionflag)) { flag [83] =1 ; return ; } if (checkonoffparameter (parameter, value, "spot\n", &odata->spot_flag)) flag [84] =1 ; return ; } if (check on off parameter (parameter, value, "background\n", &odata->background-flag)) flag [85] =1 ; return ; if (check on off parameter (parameter, value, "common region\n", &odata->region_common_flag)) flag [174] =1 ; return ;

if (check on off-parameter (parameter, value, "common spot\n", &odata->spotcommonflag)) { flag [175] =1 ; return ; if (check on off parameter (parameter, value, "common background\n", &odata->backgroundcommonflag)) { flag [176] =1 ; return ; if (checkonoffparameter (parameter, value, "common ratio\n", &odata->ratio-common-flag)) flag [148] =1 ; return ; if (check on off parameter (parameter, value, "wrt reference region\n", &odata->regionwrtreferenceflag)) { flag [300] =1 ; return ;

if (check on off-parameter (parameter, value, "wrt reference spot\n", &odata->spot_wrt_reference_flag)) { flag [301] =1 ; return ; if (check on off-parameter (parameter, value, "wrt reference background\n", &odata->backgroundwrtreferenceflag)) { flag [302] =l ; return ; if (check on off-parameter (parameter, value, "wrt reference ratio\n", &odata->ratio_wrt_reference_flag)) flag [303] =1 ; return ; if (check on off-parameter (parameter, value, "reference region\n", &odata->regionreferenceflag)) { flag [304] =l' ; return ;

if (check-on-off-parameter (parameter, value, "reference spot\n", &odata->spot_reference_flag)) { flag [305]=1 ; return ; if (check_on_off_parameter (parameter, value, "reference background\n", &odata->backgroundreferenceflag)) flag [306]=1 ; return ; if (check_on_off_parameter(parameter, value, "subrow\n", &odata->pin_row)) { flag [86] =1 ; return ; if (check_on_off_parameter (parameter, value, "subcol\n", &odata->pincolumn)) { flag [87] =1 ; return ;

if (check_on_off_parameter (parameter, value, "spot row\n", &odata->spot_row)) { flag [88] =l ; return ; if (check_on_off_parameter (parameter, value, "spot col\n", &odata->spot column)) { flag [89] =1 ; return ; if (check_on_off_parameter (parameter, value, "region row\n", &odata->box_row)) { flag [90] =l ; return ; if (check_on_off_parameter (parameter, value, "region col\n", &odata->box-column)) flag [91]=1 ; return ;

if (check on off parameter (parameter, value, "spot spot row\n", &odata->spot_ybar)) flag [102] =l ; return ; if (checkphoffparameter (parameter, value, "spot spot col\n", &odata->spotxbar)) { flag [103] =1 ; return ; } if (checkonoffparameter (parameter, value, "spot perimeter\n", &odata->spot_perimeter)) { flag [114] =l ; return ; if (check_on_off_parameter (parameter, value, "spot width\n", &odata->spot_width)) flag [115] =1 ; return ;

if (check on off parameter (parameter, value, "spot height\n", &odata->spot_height)) { flag [116] =1 ; return ; if (check on off parameter (parameter, value, "spot rbar\n", &odata->spot_rhar)) flag [117] =1 ; return ; if (check on off parameter (parameter, value, "spot rmin\n", &odata->spot_rmin)) { flag [118] =1 ; return ; if (check_on_off_parameter (parameter, value, "spot rmax\n", &odata->spot_rmax)) flag[119]=1 ; return ; }

if (check_on_off_parameter(parameter, value, "slope\n", &odata->slope)) { flag [170]=1 ; return ; } if (check on off parameter (parameter, value, "intercept\n",<BR> &odata->intercept)) { flag [171] =1 ; return ; if (check_on_off_parameter (parameter, value, "R\n" &odata->R)) flag [171] =1 ; return ; if (checkonoffparameter (parameter, value, "row shift\n", &odata->row_shift)) flag [152] =1 ; return ; if (check_on_off_parameter (parameter, value, "col shift\n",

&odata->col_shift)) { flag [153] =1 ; return ; } if (check on off parameter (parameter, value, "grid row\n", &odata->gridrow)) { flag [307] =1 ; return ;. if (check on off parameter (parameter, value, "grid col\n", &odata->gridcolumn)) { flag [308] =1 ; return ; <BR> <BR> <BR> <BR> <BR> if (check on off parameter (parameter, value, _ "box distance to grid\n", &odata->box_dist_to_grid)) flag [309] =1 ; return ; if (check on off-parameter (parameter, value, "spot distance to grid\n", &odata->spotdisttogrid)) { flag [310] =1 ; return ;

if (checkonoffparameter (parameter, value, "spot number\n", &odata->spotnumber)) { flag [311] =l ; return ; if (strcmp (parameter,"average\n") ==0) { if ((strcmp(value, "on\n")==0) # # (strcmp(value, "off\n"))) if (strcmp (value, "on\n")==0) printf ("average flag set to on\n") ; setvalue=l ; else { printf ("average flag set to off\n") ; set value=0 ; flag [154] =1 ; odata->region. average=set_value ; odata->spot. average=setvalue ; odata->background. average=set value ; odata->ratiowrtreference. average=setvalue ; odata->regionwrtreference. average=set value ; odata->spotwrtreference. average=setvalue ; odata->backgroundwrtreference. average=setvalue ;

odata->regionreference. average=setvalue ; odata->spotreference. average=setvalue ; odata->backgroundreference. average=set value ; odata->ratiocommon. average=setvalue ; odata->region_common. average=setvalue ; odata->spotcommon. average=setvalue ; odata->background_common. average=set_value ; } if (strcmp (parameter, "std_dev\n")==0) if ( (strcmp (value,"on\n") ==0) ## (strcmp (value, "off\n"))) { if (strcmp (value, "on\n")==0) printf ("std dev flag set to on\n") ; set value=1 ; else { printf ("std dev flag set to off\n") ; set value=0 ; flag [155] =1 ; odata->region. std_dev=set_value ; odata->spot. stddev=setvalue ; odata->background. stddev=setvalue ; odata->ratiowrtreference. stddev=setvalue ; odata->region_wrt_reference.std_dev=set_value ;

odata->spotwrtreference. stddev=setvalue ; odata->backgroundwrtreference. stddev=setvalue ; odata->regionreference. stddev=setvalue ; odata->spot_reference.std_dev=set_value ; odata->backgroundreference. stddev=setvalue ; odata->ratiocommon. stddev=setvalue ; odata->regioncommon. stddev=setvalue ; odata->spotcommon. stddev=setvalue ; odata->backgroundcommon. stddev=setvalue ; if (strcmp (parameter,"median\n") ==0) { if ( (strcmp (value,"on\n") ==0) jj (strcmp (value, "off\n"))) { if (strcmp (value, "on\n")==0) printf ("median flag set to on\n") ; set value=1 ; else { printf ("median flag set to off\n") ; set value=0 ; flag [156] =1 ; odata->region. median=setvalue ; odata->spot. median=setvalue ; odata->background. median=setvalue ;

odata->ratio_wrt_reference.median=set_value ; odata->regionwrtreference. median=setvalue ; odata->spotwrtreference. median=setvalue ; odata->backgroundwrtreference. median=setvalue ; odata->regionreference. median=setvalue ; odata->spotreference. median=setvalue ; odata->backgroundreference. median=setvalue ; odata->ratiocommon. median=set value ; odata->regioncommon. median=set value ; odata->spotcommon. median=set value ; odata->backgroundcommon. median=setvalue ; if (strcmp (parameter, "average_one_sd\n")==0) if ((strcmp(value, "on\n")==0) ## (strcmp (value, "off\n"))) { if (strcmp (value, "on\n")==0) printf ("average one std dev flag set to on\n") ; set value=1 ; else { printf ("average one std dev flag set to off\n") ; set value=0 ; flag [157] =1 ; odata->region. averageonesd=setvalue ; odata->spot. averageonesd=setvalue ;

odata->background. averageonesd=setvalue ; odata->ratiowrtreference. averageonesd=setvalue ; odata->regionwrtreference. averageonesd=setvalue ; odata->spotwrtreference. averageonesd=setvalue ; <BR> <BR> odata->backgroundwrtreference. averageonesd=setvalu e ; odata->regionreference. averageonesd=setvalue ; odata->spot_reference.average_one_sd=set_value ; odata->background_reference.average_one_sd=set_value ; odata->ratiocommon. averageonesd=setvalue ; odata->region_common.average_one_sd=set_value ; odata->spotcommon. averageonesd=setvalue ; odata->background_common.average_one_sd=set_value ; if (strcmp (parameter, "average_two_sd\n")==0) if ((strcmp(value, "on\n")==0) ## (strcmp (value, "off\n"))) if (strcmp (value, "on\n")==0) printf ("average two std dev flag set to on\n") ; set value=1 ;

else { printf ("average two std dev flag set to off\n") ; set value=0 ; } flag [158] =1 ; odata->region. averagetwosd=setvalue ; odata->spot. averagetwosd=setvalue ; odata->background. averagetwosd=setvalue ; odata->ratiowrtreference. averagetwosd=setvalue ; odata->regionwrtreference. averagetwosd=setvalue ; odata->spot_wrt_reference.average_two_sd=set_value ; <BR> <BR> <BR> <BR> <BR> <BR> odata->backgroundwrtreference. averagetwosd=setvalu e ; odata->region_reference.average_two_sd=set_value ; odata->spot_reference.average_two_sd=set_value ; odata->background_reference.average_two_sd=set_value ; odata->ratio_common. averagetwosd=setvalue ; odata->region_common. average_two_sd=set_value ; odata->spotcommon. averagetwosd=setvalue ; odata->backgroundcommon. averagetwosd=setvalue ; }

if (strcmp (parameter,"area\n") ==0) { if ((strcmp(value, "on\n")==0) ## (strcmp (value, "off\n"))) { if (strcmp (value,"on\n") ==0) { printf ("area flag set to on\n") ; set value=1 ; else { printf ("area flag set to off\n") ; set value=0 ; } flag [159] =1 ; odata->region. area=set_value ; odata->spot. area=setvalue ; odata->background. area=setvalue ; odata->ratiowrtreference. area=setvalue ; odata->regionwrtreference. area=setvalue ; odata->spotwrtreference. area=setvalue ; odata->backgroundwrtreference. area=setvalue ; odata->regionreference. area=setvalue ; odata->spotreference. area=setvalue ; odata->backgroundreference. area=setvalue ; odata->ratiocommon. area=setvalue ; odata->regioncommon. area=setvalue ; odata->spot_>common. area=setvalue ; odata->backgroundcommon. area=setvalue ;

} if (strcmp (parameter, "area_one_sd\n")==0) { if ((strcm(value, "on\n")==0) ## (strcmp (value, "off\n"))) { if (strcmp (value,"on\n") ==0) { printf ("area one sd flag set to on\n") ; setvalue=l ; else { printf ("area one sd flag set to off\n") ; set value=0 ; flag [160] =1 ; odata->region. area_one_sd=set_value ; odata->spot. areaonesd=setvalue ; odata->background. areaonesd=setvalue ; odata->ratio_wrt_reference.area_one_sd=set_value ; odata->regionwrtreference. areaonesd=setvalue ; odata->spotwrtreference. areaonesd=setvalue ; odata->backgroundwrtreference. areaonesd=setvalue ; odata->regionreference. areaonesd=setvalue ; odata->spotreference. areaonesd=setvalue ; odata->background_reference.area_one_sd=set_value ;

odata->ratio_common.area_one_sd=set_value ; odata->region_common. areaonesd=setvalue ; odata->spotcommon. areaonesd=setvalue ; odata->backgroundcommon. areaonesd=set value ; if (strcmp (parameter, "area_two_sd\n") ==0) { if ((strcmp(value, "on\n")==0) ## (strcmp (value, "off\n"))) { if (strcmp (value, "on\n")==0) printf ("area_two_sd flag set to on\n") ; set value=1 ; else { printf ("area two-sd flag set to off\n") ; set value=0 ; flag [161] =1 ; odata->region. areatwosd=setvalue ; odata->spot. are_two_sd=set_value ; odata->background. areatwosd=setvalue ; odata->ratiowrtreference. areatwosd=set value ; odata->regionwrtreference. areatwosd=setvalue ; odata->spotwrtreference. areatwosd=set value ; odata->backgroundwrtreference. areatwosd=setvalue ;

odata->region reference. area two_sd=set value ; odata->spotreference. areatwosd=setvalue ; odata->backgroundreference. areatwosd=setvalue ; odata->ratiocommon. areatwosd=setvalue ; odata->regioncommon. areatwosd=setvalue ; odata->spotcommon. areatwosd=setvalue ; odata->backgroundcommon. areatwosd=setvalue ; if (strcmp (parameter, "area_zero\n") ==0) { if ((strcmp(value, "on\n")==0) ## (strcmp (value, "off\n"))) { if (strcmp (value, "on\n")==0) { printf ("area-zero flag set to on\n") ; set value=1 ; else { printf ("area_zero flag set to off\n") ; set_value=0 ; flag [162] =1 ; odata->region. areazero=setvalue ; odata->spot. areazero=setvalue ; odata->background. areazero=setvalue ; odata->ratiowrtreference. areazero=setvalue ; odata->regionwrtreference. areazero=setvalue ;

odata->spot_wrt reference. area zero=set value ; _ odata->backgroundwrtreference. areazero=setvalue ; odata->regionreference. areazero=setvalue ; odata->spotreference. areazero=setvalue ; odata->background_reference.area_zero=set_value; odata->ratiocommon. areazero=setvalue ; odata->regioncommon. areazero=setvalue ; odata->spotcommon. areazero=setvalue ; odata->backgroundcommon. areazero=setvalue ; if (strcmp (parameter, "area_saturated\n")==0) if ((strcmp(value, "on\n")==0) ## (strcmp (value, "off\n"))) { if (strcmp (value, "on\n")==0) printf ("area-saturated flag set to on\n") ; set value=1 ; else { printf ("area-saturated flag set to off\n") ; set_value=0 ; } flag [163] =1 ; odata->region. areasaturated=setvalue ; odata->spot. area saturated=setvalue ; odata->background. areasaturated=setvalue ;

odata->ratio_wrt_reference.area_saturated=set_value; odata->regionwrtreference. areasaturated=setvalue ; odata->spot_wrt_reference.area_saturated=set_value; <BR> <BR> odata->backgroundwrtreference. areasaturated=setvalu odata->region_reference.area_saturated=set_value; odata->spotreference. areasaturated=setvalue ; odata->background_reference.area_saturated=set_value; odata->ratio_common.area_saturated=set_value; odata->regioncommon. areasaturated=setvalue ; odata->spotcommon. areasaturated=setvalue ; odata->background_common. areasaturated=setvalue ; if (strcmp (parameter,"min\n") ==0) { if ((strcmp(value, "on\n")==0) ## (strcmp (value, "off\n"))) { if (strcmp (value, "on\n")==0) printf ("min flag set to on\n") ; set_value=l ;

else { printf ("min flag set to off\n") ; set value=0 ; flag [164] =1 ; odata->region. min=setvalue ; odata->spot. min=setvalue ; odata->background. min=setvalue ; odata->ratiowrtreference. min=setvalue ; odata->region_wrt_reference.min=set_value ; odata->spotwrtreference. min=setvalue ; odata->backgroundwrtreference. min=setvalue ; odata->region_reference.min=set_value ; odata->spotreference. min=setvalue ; odata->background_reference.min=set_value ; odata->ratiocommon. min=setvalue ; odata->regioncommon. min=set value ; odata->spotcommon. min=setvalue ; odata->backgroundcommon. min=setvalue ; if (strcmp (parameter,"max\n") ==0) { if ((strcmp(value, "on\n")==0) ## (strcmp (value, "off\n"))) { \n"))) if (strcmp (value, "on\n")==0) printf ("max flag set to on\n") ; set value=1 ;

} else { printf ("max flag set to off\n") ; set value=0 ; flag [165] =1 ; odata->region. max=setvalue ; odata->spot. max=setvalue ; odata->background. max=setvalue ; odata->ratiowrtreference. max=setvalue ; odata->regionwrtreference. max=setvalue ; odata->spotwrtreference. max=setvalue ; odata->backgroundwrtreference. max=setvalue ; odata->regionreference. max=set value ; odata->spotreference. max=setvalue ; odata->backgroundreference. max=setvalue ; odata->ratiocommon. max=setvalue ; odata->region_common. max=setvalue ; odata->spot_common. max=setvalue ; odata->backgroundcommon. max=setvalue ; } if (strcmp (parameter, "path\n")==0) odata->outputpath= (char *) malloc (strlen (value) *sizeof (char)) ; if (odata->output {

printf ("Failed malloc for odata->output_path in get_output_data_param... \n") ; exit (-l) ; strncpy (odata->output_path, value, strlen (value)-l) ; flag [169]=1 ; odata->output-path [strlen (value)-1] =0 ; printf ("path = %s\n", odata->output_path) ; return ; if ( (stat_ptr=check_parameter (parameter,"region ")) ! =NULL) { temp = read_statistics_parameter (&odata->region, statptr, value) ; if ( (temp>-l) && (temp<10) flag [92+temp] =1 ; return ; } else if (temp>9) { flag [132+temp-10]=1 ; return ; if ( (stat_ptr=check_parameter (parameter,"spot ")) ! =NULL) {

temp = read statistics parameter (&odata->spot, statptr, value) ; if( (temp>-1) && (temp<10) flag [104+temp] =l ; return ; else if (temp>9) { flag [134+temp-10] =1 ; return ; if ( (stat_ptr=check_parameter (parameter,"background " ! =NULL temp = read statistics parameter (&odata->background, stat_ptr, value) ; if ( (temp>-l)) { flag [120+temp] =1 ; return ; } if ( (stat_ptr=check_parameter (parameter,"common region")) ! =NULL) { temp = read_statistics_parameter(&odata->region_common, stat_ptr, value) ;

if ( (temp>-l)) { flag [177+temp] =1 ; return ; if ( (stat_ptr=check_parameter (parameter,"common spot "))!=NULL ) { temp = read_statistics_parameter (&odata->spot_common, stat_ptr, value) ; if ( (temp>-l)) { flag [189+temp] =1 ; return ; } if ( (stat_ptr=check_parameter (parameter,"common background "))!=NULL ) temp = read_statistics_parameter(&odata->background_common, stat_ptr, value) ; if ( (temp>-l)) { flag [201+temp]=1 ; return ;

if ( (stat_ptr=check_parameter(parameter, "common ratio ")) ))!=NULL temp = readstatisticsparameter (&odata->ratiocommon, statptr, value) ; if ( (temp>-l)) { flag [136+temp] =1 ; return ; if ( (stat_ptr=check_parameter(parameter,"wrt reference region")) ! =NULL) { temp = <BR> readstatisticsparameter (&odata->regionwrtreference, stat_ptr, value) ; if( (temp>-1) flag [216+temp]=1 ; return ; if ( (stat_ptr=check_parameter (parameter,"wrt reference spot "))!=NULL) temp = <BR> read-statistics-Parameter (&odata->spotwrtreference, stat-ptr, value) ; if ( (temp>-l)) {

flag [228+temp] =1 ; return ; if ( (statptr=checkparameter (parameter,"wrt reference background")) ! =NULL) { temp = read_statistics_parameter(&odata->background_wrt_refere nce, stat_ptr, value) ; if ( (temp>-l)) { flag [240+temp] =1 ; return ; if ( (statptr=checkparameter (parameter,"wrt reference ratio")) ! =NULL) { temp = read_statistics_parameter(&odata->reatio_wrt_reference, stat_ptr, value) ; if ( (temp>-l)) { flag [252+temp] =1 ; return ;

if ( (stat_ptr=check_parameter (parameter,"reference region")) !=NULL ) temp = readstatisticsparameter (&odata->regionreference, stat_ptr, value) ; if ( (temp>-l)) { flag [264+temp] =1 ; return ; if ( (stat_ptr=check_parameter (parameter,"reference spot "))!=NULL ) temp = read_statistics_parameter(&odata->spot_reference, stat_ptr, value) ; if ( (temp>-l)) { flag [276+temp] =1 ; return ; if ( (stat_ptr=check_parameter (parameter,"reference background "))!=NULL ) temp = read_statistics_parameter(&odata->background_reference, stat_ptr, value) ; if ( (temp>-l)) {

flag [288+temp] =1 ; return ; printf ("#did not find an output data flag %s\n", parameter) ; void read parameters (struct parameters *p, char *fname) FILE *printer-file ; char *pname, *number ; int i, flag [PARAMETER_ENTRIES] ; number= (char *) malloc (getpagesize () *sizeof (char)) ; pname= (char *) malloc (getpagesize () *sizeof (char)) i printer-file = fopen (fname,"r") ; if (printer-file==NULL) {printf ("Printer file s does not exist. \n", fname) ; exit (-l) ; for (i=0 ; i<PARAMETER ENTRIES ; i++) flag [i] =0 ;

do { fgets (number, getpagesize (), printer_file) ; if (feof (printer-file) ==0) { /*set up the strings*/ for (i=0 ; (i< (int) strlen (number)) && (number [i] !=9) ; i++) ; if ((i+!) < (int) strlen (number)) {strcpy (pname, &number [i+l]) ; number [i] ='\n'; number [i+l] =0 ; else strcpy (pname,"") ; if (strcmp (pname,"spot type list\n") ==0) { flag [214] =1 ; if (strcmp (number,"generic\n") ==0) { printf ("#spot type list = %s\n", number) ; readspottypesgeneric (&p->printerinfo, printer_file) ; else { printf ("#spot type list = os is unknown ! ! ! \n", number) ; } continue ;

if (strcmp (pname,"gene id list\n") ==0) { flag [215] =1 ; if (strcmp (number,"generic\n") ==0) { printf ("#gene id list = % s\n", number) ; read_gene-id generic (&p->printer-info, printer-file) ; else if (strcmp (number,"corning\n") ==0) { printf ("#gene id list = %s\n", number) ; readgeneidcorning (&p->printerinfo, printer-file) ; else { printf ("&num spot type list = os is unknown ! ! ! \n", number) ; } continue ; if (strcmp (pname,"find boxes limit furcation\n") ==0) P [0]. find boxes. limit_furcation=atoi (number) ; flag [0] =1 ; printf ("#find boxes limit furcation = %i\n", p [0]. find-boxes. limit-furcation) ; s /* Find boxes */

if (strcmp (pname,"find boxes limit center\n") ==0) {p [0]. findboxes. limitcenter=atoi (number) ; flag [l] =l ; printf ("&num find boxes limit center = %i\n", p [0]. find_boxes.limit_center) ; if (strcmp (pname,"find boxes fraction by furcation\n") ==0) { p [0]. find boxes. fraction by_furcation=atof (number) ; flag [2] =1 ; printf ("&num find boxes fraction by furcation = %f\n", p [0]. find boxes. fraction by furcation) ; } if (strcmp (pname,"find boxes center tolerance\n") ==0) { p[0].find_boex.center_tolerance=atof (number) ; flag [3] =1 ; printf ("#find boxes center tolerance = %f\n", p [0]. find_boxes.center_tolerance) ; if (strcmp (pname,"find boxes spot params crop width\n") ==0)

p [0]. find boxes. spot_params. crop width=atoi (number) ; flag [4] =1 ; printf ("#find boxes spot params crop width = %i\n", p [0]. findboxes. spotparams. cropwidth) ; if (strcmp (pname,"find boxes spot params crop height\n") ==0) p [0]. findboxes. spotparams. cropheight=atoi (number) ; flag [5] =1 ; printf ("#find boxes spot params crop height = %i\n", p [0]. findboxes. spotparams. cropheight) ; if (strcmp (pname,"find boxes spot params furcation type\n") ==0) if (strcmp (number,"simple\n") ==0) p [0]. findboxes. spotparams. furcation type=SIMPLE ; flag [6] =1 ; printf ("#find boxes spot params furcation type = simple\n") ; if (strcmp (number,"holefill\n") ==0) p [0]. findboxes. spotparams. furcationtype=HOLEFILL ;

flag [6] =1 ; printf ("#find boxes spot params furcation type = holefill\n") ; if (strcmp (number,"edgereject\n") ==0) p [0]. find boxes. spot_params. furcation type=EDGEREJECT ; flag [6] =1 ; printf ("#find boxes spot params furcation type = edgereject\n") ; if (strcmp (number,"edgerejectholefill\n") ==0) p [0]. findboxes. spotparams. furcationtype=EDGEREJECTH OLEFILL ; flag [6] =1 ; printf ("#find boxes spot params furcation type = edgereject and holefill\n") ; } if (strcmp (pname,"find boxes spot params fraction Ibar\n") ==0) p [0]. findboxes. spotparams. fractionIbar=atof (number) ; flag [7] =1 ; printf ("#find boxes spot params fraction Ibar = %f\n", p [0]. findboxes. spotparams. fractionIbar) ;

if (check on off parameter (pname, number, "map spots pin by pin range row autoselect\n", <BR> &p [0]. mapspots. rangecoarsepinby<BR> pin row autoselect)) { flag [8] =1 ; continue ; if (check on off parameter (pname, number, "map spots pin by pin range column autoselect\n", &p [0]. map-spots. rangecoarsepinbypincolautoselect) flag [9] =1 ; continue ; /* Crop image params */ if (strcmp (pname,"crop image data spot params crop width\n") ==0) p [0]. crop_image_data.spot_params.crop_width=atoi (number ) i flag [18] =1 ;

printf ("#crop image data spot params crop width = %i\n", p [0]. crop_image_data.spot_params.crop_width) ; if (strcmp (pname,"crop image data spot params crop height\n") ==0) p [0]. crop_image_data.spot_params.crop_height=atoi (numbe r) ; flag [19] =1 ; printf ("#crop image data spot params crop height = %i\n", p [0]. crop_image_data.spot_params.crop_height) ; if (strcmp (pname,"crop image data spot params furcation type\n") ==0) if (strcmp (number, "simple\n")==0) p [0]. cropimagedata. spotparams. furcationtype=SIMPLE ; flag [20] =1 ; printf ("#crop image data spot params furcation type = simple\n") ; if (strcmp (number,"holefill\n") ==0) p [0]. crop_image_data. spot params. furcation_type=HOLEFIL L ;

flag [20] =1 ; printf ("&num crop image data spot params furcation type = holefill\n") ; if (strcmp (number,"edgereject\n") ==0) p [0]. cropimagedata. spotparams. furcationtype=EDGEREJ ECT ; flag [20] =1 ; printf ("#crop image data spot params furcation type = edgereject\n") ; if (strcmp (number,"edgerejectholefill\n") ==0) p [0]. crop_image_data. spot params. furcation type=EDGEREJ ECTHOLEFILL ; flag [20] =1 ; printf ("#crop image data spot params furcation type = edgereject and holefill\n") ; if (strcmp (pname,"crop image data spot params fraction Ibar\n") ==0) f p[0].crop_image_data.spot_params.fraction_Ibar=atof (num ber) ; flag [21] =l ;

printf ("#crop image data spot params fraction Ibar = Wf\n", p [0]. crop_image_data.spot_params.fraction_Ibar) ; } /* Output image */ if (check_on_off_parameter (pname, number, "output image tiff zip\n", &p [0]. output-image. tiff_zip_flag)) flag [22] =1 ; continue ; } if (check_on_off_parameter (pname, number, "output image tiff jpg\n", &p [0]. output-image. tiff_jpg_flag)) flag [23] =1 ; continue ; if (check on off parameter (pname, number, "output, image jpg\n", &p [0]. output_image. jpg_flag)) { flag [24] =1 ; continue ; if (check on off parameter (pname, number,

"output image ppm\n", &p [0]. outputimage. ppmflag)) { flag [25]=1 ; continue ; if (check-on-off-parameter (pname, number, "output image grid\n", &p [0]. outputimage. gridflag)) { flag [26] =1 ; continue ; if (strcmp (pname,"output image perimeter\n") ==O) if (strcmp (number,"on\n") ==0) {p [0]. output_image. perimeter-flag=1 ; flag [27] =l ; printf ("#output image perimeter flag set to on\n") ; } if (strcmp (number,"off\n") ==0) {p [0]. output-image. perimeter-flag=0 ; flag [27]=1 ; printf ("#output image perimeter flag set to off\n") ; if (strcmp (pname,"output image integrated\n") ==O) {if (strcmp (number,"on\n") ==0)

p [0]. output_image. integrated flag=1 ; flag [28] =1 ; printf ("#output image integrated flag set to on\n") ; if (strcmp (number,"off\n") ==0) p [0]. output_image. integrated-flag=0 ; flag [28] =1 ; printf ("#output image integrated flag set to off\n") ; } if (strcmp (pname,"output image jpg quality\n") ==0) {p [0]. output_image. jpg_quality=atoi (number) ; flag [29] =1 ; printf ("&num output image jpg qualtity = %i=n", p [0]. output_image. jpg_quality) ; /* Integration params */ if (strcmp (pname,"integration mask\n") ==0) {if (strcmp (number,"on\n") ==0) p [0]. integration. mask_flag=l ; flag [30] =1 ; printf ("#integration mask flag set to on\n") ;

if (strcmp (number,"off\n") ==0) {p [0]. integration. mask-flag=0 ; flag [30] =1 ; printf ("#integration mask flag set to off\n") ; } if (strcmp (pname,"integration square\n") ==0) {if (strcmp (number,"on\n") ==0) {p [0]. integration. square flag=1 ; p [0]. integration. mask_flag=0 ; flag [31] =1 ; printf ("#integration square flag set to on\n") ; if (strcmp (number,"off\n") ==0) {p [0]. integration. square-flag=0 ; flag [31] =1 ; printf ("#integration square flag set to off\n") ; if (strcmp (pname,"integration circle\n") ==0) if (strcmp (number,"on\n") ==0) {p [0]. integration. circle_flag=1 ;

p [0]. integration. mask_flag=1 ; flag [32] =1 ; printf ("#integration circle flag set to on\n") ; if (strcmp (number,"off\n") ==0) {p [0]. integration. circle-flag=0 ; flag [32] = 1 ; printf ("#integration circle flag set to off\n") ; if (strcmp (pname,"integration donut\n") ==0) if (strcmp (number,"on\n") ==0) {p [0]. integration. donut-flag=1 ; flag [33] =1 ; printf ("#integration donut flag set to on\n") ; if (strcmp (number,"off\n") ==0) p [0]. integration. donut_flag=0 ; flag [33] =1 ; printf ("#integration donut flag set to off\n") ;

if (strcmp (pname,"integration radius\n") ==0) p [0]. integration. integrationradius=atoi (number) ; flag [34] =1 ; printf ("#integration radius = %i\n", p [0]. integration. integration radius) ; } if (strcmp (pname,"integration width\n") ==0) p [0]. integration. integrationwidth=atoi (number) ; flag [35] =1 ; printf ("#integration width = %i\n", p [03. integration. integration-width) ; if (strcmp (pname,"integration height\n") ==0) p [0]. integration. integrationheight=atoi (number) ; flag [36] =1 ; printf ("#integration height = %i\n", p [0]. integration. integration_height0 ; } /* Integration out */ if (strcmp (pname,"integration out mask\n") ==0) {if (strcmp (number,"on\n") ==0)

{p [0]. integrationout. maskflag=l ; flag [37] =1 ; printf ("#integration out mask flag set to on\n") ; if (strcmp (number,"off\n") ==0) {p [0]. integration out. mask-flag=0 ; flag [37] =1 ; printf ("#integration out mask flag set to off\n") ; if (strcmp (pname,"integration out square\n") ==0) if (strcmp (number,"on\n") ==0) {p [0]. integrationout. squareflag=l ; p [0]. integration_out.mask-flag=0 ; flag [38] =1 ; printf ("#integration out square flag set to on\n") ; if (strcmp (number,"off\n") ==0) { p[0]. integration_out.square_flag=0 ; flag [38] =1 ; printf ("#integration out square flag set to off\n") ; }

if (strcmp (pname,"integration out circle\n") ==0) {if (strcmp (number,"on\n") ==0) {p [0]. integrationout. circleflag=l ; p [o]. integration_out.mask_flag=1 ; flag [39] =1 ; printf ("#integration out circle flag set to on\n") ; if (strcmp (number,"off\n") ==0) {p [0]. integration_out.circle_flag=0 ; flag [39] =1 ; printf ("#integration out circle flag set to off\n") ; if (strcmp (pname,"integration out donut\n") ==0) if (strcmp (number,"on\n") ==0) p [0]. integration_outp.donut_flag=1 ; flag [40] =1 ; printf ("#integration out donut flag set to on\n") ; } if (strcmp (number,"off\n") ==0) {p [0]. integrationout. donutflag=0 ; flag [40] =1 ; printf ("#integration out donut flag set to off\n") ;

if (strcmp (pname,"integration out radius\n") ==0) p [0]. integrationout. integrationradius=atoi (number) ; flag [41] =1 ; printf ("#integration out radius = % i\n", p [0]. integration out. integration radius) ; if (strcmp (pname,"integration out width\n") ==0) p [0]. integrationout. integrationwidth=atoi (number) ; flag [42] =1 ; printf ("&num integration out width = % i\n", p [0]. integration out. integration width) ; } if (strcmp (pname,"integration out height\n") ==0) p [0]. integrationout. integrationheight=atoi (number) ; flag [43] =1 ; printf ("#integration height = % i\n", p [0]. integration_out.integration_height) ; /* Find angles */

if (strcmp (pname,"find angles do find angles\n") ==0) {if (strcmp (number,"on\n") ==0) {p [0]. findangles. dofindangles=l ; flag [44] =1 ; printf ("#do find angles flag set to on\n") ; if (strcmp (number, "off\n") ==0) {p [0].. find angles. do-find angles=0 ; flag [44] =1 ; printf ("&num do find angles flag set to off\n") ; if (strcmp (pname,"find angles iteration limit\n") ==0) {p[0]. find_angles.iteration_limit=atoi (number) ; flag [45] =1 ; printf ("#find angles iteration limit = %i\n", p [0]. find_angles.iteration_limit) ; if (strcmp (pname,"find angles x-vector tolerance\n") ==0) { p [0]. find-angles. x vector tolerance=atof (number) ; _ flag [46] =1 ;

printf ("#find angles x-vector tolerance = % f\n", p [0]. findangles. xvectortolerance) ; if (strcmp (pname,"find angles y-vector tolerance\n") ==0) p [0]. findangles. yvectortolerance=atof (number) ; flag [47] =1 ; printf ('#find angles y-vector tolerance = %f\n", p [0]. find angles. y vector tolerance) ; if (strcmp (pname,"find angles convergence distance\n") ==0) p [0]. findangles. convergencedistance=atof (number) ; flag [48] =1 ; printf ("#find angles convergence distance = %f\n", p [0]. find angles. convergence distance) ; /* Map spots */ if (strcmp (pname,"map spots do coarse\n") ==0) {if (strcmp (number,"on\n") ==0) p [0]. map-spots. docoarse=l ; flag [49] =1 ;

printf ("&num map spots do coarse flag set to on\n") ; if (strcmp (number,"off\n") ==0) {p [0]. map_spots. do_coarse=0 ; flag [49] =1 ; printf ("#map spots do coarse flag set to off\n") ; if (strcmp (pname,"map spots do fine\n") ==0) {if (strcmp (number,"on\n") ==0) {p [0]. map-spots. do_fine=1 ; flag [50] =1 ; printf ("#map spots do fine flag set to on\n") ; if (strcmp (number,"off\n") ==0) p [0]. map_spots. domine=0 ; flag [50] =1 ; printf ("#map spots do fine flag set to off\n") ; if (strcmp (pname,"map spots do coarse pin by pin\n") ==0)

{if (strcmp (number,"on\n") ==0) p [0]. map-spots. do coarse pin by pin=1 ; flag [51] =1 ; printf ("#map spots do coarse pin by pin flag set to on\n") ; if (strcmp (number,"off\n") ==0) {p [0]. map_spots.do_coarse_pin_by_pin=0 ; flag [51] =1 ; printf ("#map spots do coarse pin by pin flag set to off\n") ; } if (strcmp (pname,"map spots do distance\n") ==0) if (strcmp (number,"on\n") ==0) {p [0]. map_spots. do distance=1 ; flag [52] =1 ; printf ("#map spots do distance flag set to on\n") ; if (strcmp (number,"off\n") ==0) {p [0]. map-spots. do_distance=0 ; flag [52] =1 ; printf ("#map spots do distance flag set to off\n") ;

if (strcmp (pname,"map spots increment coarse\n") ==0) {p [0]. map-spots. incrementcoarse=atoi (number) ; flag [53] =1 ; printf ("#map spots increment coarse = %i\n", p [0]. map_spots.increment_cvoarse) ; if (strcmp (pname,"map spots increment fine\n") ==0) {p [0]. map_spots. increment_fine=atoi (number) ; flag [54] =1 ; printf ("#map spots increment fine = % i\n", p [0]. map-spots. increment-fine) ; if (strcmp (pname,"map spots increment coarse pin by pin\n") ==0) p [0]. map_spots. incrementcoarsepinbypin=atoi (number) : flag [55] =1 ; printf ("#map spots increment coarse pin by pin = %i\n", p [0]. map-spots. incrementcoarsepinbypin) ; } if (strcmp (pname,"map spots increment distance\n") ==0) p [0]. map_spots. incrementdistance=atoi (number) ; flag [56] =1 ;

printf ("&num map spots increment distance = %i\n", p [0]. map_spots.increment_+distance) ; if (strcmp (pname,"map spots range fine row\n") ==0) {p [0]. mapspots. rangefinerow=atoi (number) ; flag [57]=1 ; printf ("#map spots range fine row = %i\n", p [0]. mapspots. rangefinerow) ; if (strcmp (pname,"map spots range fine column\n") ==0) p [0]. map-spots. rangefinecolumn=atoi (number) ; flag [58] =1 ; printf ("#map spots range fine column = %i\n", p [0]. mapspots. rangefinecolumn) ; if (strcmp (pname,"map spots range coarse pin by pin row\n") == 0) p [0]. map-spots. rangecoarsepinbypinrow=atoi (number) flag [59] =1 ; printf ("#map spots range coarse pin by pin row = %i\n", p [0]. map-spots. rangecoarsepinbypinrow) ; if (strcmp (pname,"map spots range coarse pin by pin column\n") ==0)

p [0]. map_spots. rangecoarsejpinbypincolumn=atoi (numb er) ; flag [60]=1 ; printf ("#map spots range coarse pin by pin column = %i\n", p [0]. map_spots. rangecoarsepinbypincolumn) ; if (strcmp (pname,"map spots range distance row\n") ==0) p [0]. map-spots. rangedistancerow=atoi (number) ; flag [61] =1 ; printf ("#map spots range distance row = %i\n", p [0]. mapspots. rangedistancerow) ; } if (strcmp (pname,"map spots range distance column\n") ==0) p [0]. map-spots. rangedistancecolumn=atoi (number) ; flag [62] =1 ; printf ("#map spots range distance column = %i\n", p [0]. map-spots. range distance-column) ; /* Fermi level for Gen-1 inspection */ if (strcmp (pname,"genl fermi level\n") ==0) {p [0]. genlfermilevel=atof (number) ;

flag [63] =1 ; printf ("#The Gen-1 inspection fermi level has been set to %f\n", p [0]. gen1_fermi_level) ; /* Background */ if (strcmp (pname,"background mask file\n") ==0) if (. strcmp (number,"on\n") ==0) p [0]. background. mask-file-flag=1 ; flag [64] =1 ; printf ("#background mask file flag set to on\n") ; if (strcmp (number,"off\n") ==0) p [0]. background. mask-file_flag=0 ; flag [64] =1 ; printf ("#background mask file flag set to off\n") ; if (strcmp (pname,"background square\n")==0) if (strcmp (number,"on\n") ==0) p [o]. background. square flag=l ; p [0]. background. mask_flag=0 ; flag [65] =1 ; printf ("#background square flag set to on\n") ;

if (strcmp (number,"off\n") ==0) {p [0]. background. square_flag=0 ; flag [65] =1 ; printf ("&num background square flag set to off\n") ; if (strcmp (pname,"background circle\n") ==0) {if (strcmp (number,"on\n") ==0) {p [0]. background. circle-flag=1 ; p [0]. background. mask-flag=1 ; flag [66] =1 ; printf ("&num background circle flag set to on\n") ; if (strcmp (number,"off\n") ==0) {p [0]. background. circle-flag=0 ; flag [66] =1 ; printf ("#background circle flag set to off\n") ; } if (strcmp (pname,"background mask width\n") ==0) {p [0]. background. maskwidth=atoi (number) ; flag [67] =1 ;

printf ("#background mask width = % i\n", p [0]. background. maskwidth) ; if (strcmp (pname,"background frame width\n") ==0) { p [0]. background. backgroundframewidth=atoi (number) ; flag [68] =1 ; printf ("#background frame width = %i\n", p [0]. background. background-frame-width) ; if (strcmp (pname,"background width\n") ==0) {p. [0]. background. backgroundwidth=atoi (number) ; flag [69] =1 ; printf ("#background width = % i\n", p [0]. background. background-width) ; if (strcmp (pname,"background height\n") ==0) p [0]. background. backgroundheight=atoi (number) ; flag [70] =1 ; printf ("#background height = %i\n", p [0]. background. background-height) ; if (strcmp (pname,"background radius\n") ==0) p [0]. background. backgroundradius=atoi (number) ; flag [71] =1 ; printf ("#background radius = %i\n", p [0]. background. background-radius) ;

if (strcmp (pname,"output image path\n") ==0) {p [0]. output_image. output_path= (char *) malloc (strlen (number) *sizeof (char)) ; if (p [0]. output-image. output_path==NULL) printf ("Failed malloc for p [0]. output_image. output path in read_parameters... \n") ; exit (-l) ; } strncpy (p [0]. output_image. output_path, number, strlen (number)-1) ; flag [72] =1 ; p [0]. output-image. output_path [strlen (number)-1] =0 ; printf ("#output image path = % s\n", p [0]. output-image. output_path) ; if (strcmp (pname,"map spots debug\n") ==0) if (strcmp (number,"on\n") ==0) p [0]. map_spots. debug=l ; flag [73] =1 ; printf ("#map spots debug flag set to on\n") ; } if (strcmp (number,"off\n") ==0) { p[0].map_spots. debug=0 ; flag [73] =1 ; printf ("#map spots debug flag set to off\n") ;

if (strcmp (pname,"force alignment\n") ==0) {if (strcmp (number,"on\n") ==0) {p [0]. printer_info.do_align=1 ; flag [74] =1 ; printf ("#image alignment forced\n") ; if (strcmp (number,"off\n") ==0) p [0]. printer-info. do align=0 ; flag [74] =1 ; printf ("#image alignment only if different sizes\n") ; if (strcmp (pname,"sub grid vectorization\n") ==0) {if (strcmp (number,"on\n") ==0) p [0]. printer-info. sub_grid vectorization=l ; flag [75] =1 ; printf ("#sub grid vectorization on\n") ; } if (strcmp (number,"off\n") ==0) {p [0]. printerinfo. subgridvectorization=0 ; flag [75] =1 ; printf ("#sub grid vectorization off\n") ; }

if (strcmp (pname,"map spots do fine pin by pin\n") ==0) if (strcmp (number,"on\n") ==0) p [0]. mapspots. dofinepinbypin=l ; flag [76] =1 ; printf ("#map spots do fine pin by pin flag set to on\n") ; if (strcmp(number, "off\n") ==0) { p[0].map_spots.do_fine_pin_by_pin=0; flag [76] =1 ; printf ("#map spots do fine pin by pin flag set to off\n") ; if (strcmp (pname,"map spots increment fine pin by pin\n") ==0) p [0]. map-spots. incrementfinepinbypin=atoi (number) ; flag [77] =1 ; printf ("#map spots increment fine pin by pin = %i\n", p [0]. map-spots. incrementfinepinbypin) ; if (strcmp (pname,"map spots range fine pin by pin row\n") ==0)

p [0]. map_spots. rangefinepinbypinrow=atoi (number) ; flag [78] =1 ; printf ("#map spots range fine pin by pin row = %i\n", p [0]. map-spots. rangefinepinbypinrow) ; if (strcmp (pname,"map spots range fine pin by pin column\n") ==0) f p [0]. map-spots. rangefinepinbypincolumn=atoi (number ) i flag [79] =1 ; printf ("#map spots range fine pin by pin column = %i\n", p [0]. map_spots. range_fine_pin_by_pin_column) ; if (strcmp (pname,"missing spot file name\n") ==0) p [0]. printer-info. spot types. filename= (char *) malloc (sizeof (char) *strlen (number)) ; if (p [0]. printerinfo. spottypes. filename==NULL) {printf ("Failed malloc for spot type filename in read_parameters... \n") ; exit (-l) ; } strcpy (p [0]. printer-info. spot types. filename, number) ;

p [0]. printer info. spot types. filename [strlen (number)-1] =0 ; printf ("#spot type file name = %s\n", p [0]. printerinfo. spottypes. filename) ; flag [80] =1 ; if (strcmp (pname,"find boxes fast\n") ==0) if (strcmp (number,"on\n") ==0) {p [0]. findboxes. fastflag=l ; printf ("#find boxes fast flag set to on... \n") ; flag [81] =1 ; if (strcmp (number,"off\n") ==0) p [0]. find_boxes.fast_flag=0 ; printf ("#find boxes fast flag set to off... \n") ; flag [81] =1 ; if (strcmp (pname,"output image background\n") ==0) {if (strcmp (number,"on\n") ==0) p [0]. output-image. background_flag=1 ; flag [82] =1 ; printf ("#output image background flag set to on\n") ;

if (strcmp (number,"off\n") ==O) {p [0]. outputimage. backgroundflag=0 ; flag [82] =1 ; printf ("#output image background flag set to off\n") ; if (strcmp (pname,"output image region\n") ==0) if (strcmp (number,"on\n") ==0) {p [0]. outputimage. regionflag=l ; flag [82] =1 ; printf ("#output image region flag set to on\n") ; if (strcmp (number,"off\n") ==0) {p [0]. output-image. region-flag=0 ; flag [82] =1 ; printf ("#output image region flag set to off\n") ; /* output data parameters */ if( (strstr(pname, "output data ")==pname) && (strlen (pname) >12)) {

printf ("#output data") ; get_output_data_param (&pname [12], number, &p->output_flags, flag) ; continue ; if (strcmp (pname,"crop image data shift\n") ==0) if (strcmp (number,"on\n") ==0) { p [0]. cropimagedata. shiftflag=l ; flag [149] =1 ; printf ("#crop image data shift flag set to on\n") ; if (strcmp (number,"off\n") ==0) { p [0]. cropimagedata. shiftflag=0 ; flag [149] =1 ; printf ("&num crop image data shift flag set to off\n") ; if (strcmp (pname,"crop image data shift range row\n") ==0)

p [0]. cropimagedata. shiftrangerow=atoi (number) ; flag [150] =1 ; printf ("#crop image data shift range row set to %i\n", atoi (number)) ; if (strcmp (pname,"crop image data shift range col\n") ==0) { p [0]. crop_image data. shift_range column=atoi (number) ; flag [151] =1 ; printf ("#crop image data shift range column set to %i\n", atoi (number)) ; } if (strcmp (pname,"include missing\n") ==0) {if (strcmp (number,"exclude\n") ==0) p [0]. printer-info. include missing=0 ; printf ("Missing spots excluded from output data... \n") ; flag [168] =1 ; } if (strcmp (number,"include\n") ==0) p [0]. printer-info. include_missing=1 ;

printf ("Missing spots included in output data... \n") ; flag [168] =1 ; } if (strcmp (number,"separate\n") ==0) {p [0]. printerinfo. includemissing=2 ; printf ("Missing spots included but separated in output data... \n") ; flag [168] =1 ; if (strcmp (pname,"alignment interpolation\n") ==0) if (strcmp (number,"on\n") ==0) p [0]. printer-info. do-interpolate=1 ; flag [173] =1 ; printf ("#interpolation for alignment set to on\n") ; if (strcmp (number,"off\n") ==0) p [0]. printer_info.do_interpolate+0 ; flag [173] =1 ; printf ("#interpolation for alignment set to off\n") ;

while (feof (printer-file) ==0) ; if ((p[0].printer_info.pins_per_row==1) && (p [0]. printer-info. pinsjpercolumn==l) && (flag [51] ==0)) {printf ("&num Only one subgrid, map spots (coarse and fine) pin by pin set to off... \n") ; p [0]. map-spots. docoarsepinbypin=0 ; p [0]. map_spots. dofinepinbypin=0 ; p [0]. map_spots. do-fine ; } if ( (p [0]. integrationout. circleflag==0) && (p [0]. integration_out.square_flag==0)) {printf ("Warning, all integration out flags turned off, default to square... \n") ; p [0]. integration_out.square-flag=1 ; if ((p[0]. integration. circle_flag==0) && (p [0]. integration. square_flag==0)) {printf ("Warning, all integration flags turned off, default to square... \n") ; p [0]. integration. square_flag=1 ;

if (flag [80] ==0) printf ("No spot type file specified... \n") ; else readspottypefile (&p [0]. printerinfo) ; for (i=0 ; i<p [0]. printer-info. spot_types.number_of_types ; i++) printf ("number of s spots=%i\n", p [0]. printer-info. spot_types. type_name [i], p [0]. printer-info. spot types. number [i]) ; free (number) ; free (pname) ; read printer info. c #include"defs. h" #define PRINTER ENTRIES 23 void read,. _printer-info (struct printer *print_info, char *fname) FILE *printer_file ; char *pname, *number ;

int i, flag [PRINTERENTRIES], er=0 ; pname = (char *) malloc (getpagesize () *sizeof (char)) ; number= (char *) malloc (getpagesize () *sizeof (char)) ; printer-file = fopen (fname,"r") ; if (printer_file==NULL) {printf ("Printer file %s does not exist... \n", fname) ; exit (-l) ; for (i=0 ; i<PRINTERENTRIES ; i++) flag [i] =0 ; do {fgets (number, getpagesize (), printer-file) ; if (feof (printer file) ==0) {for(i=0; (i< (int) strlen(number)) (number [i] ! =9) ; i++) ; if ((i+1) < (int) strlen (number)) {strcpy (pname, &number [i+l]) ; number [i] ='\n'; number [i+1] =0 ; else

strcpy (pname, " "); if (strcmp (pname,"spots per row\n") ==0) {printinfo->spotsperrow=atoi (number) ; flag [0] =1 ; printf ("#spots_per_row = %i\n", print_info->spots_per_row) ; if (strcmp (pname,"spots per column\n") ==0) {printinfo->spotspercolumn=atoi (number) ; flag [1] =1 ; printf ("#spots_per_column = %i\n", print_info->spots_per_column) ; } if (strcmp (pname,"pins per row\n") ==0) {printinfo->pinsperrow=atoi (number) ; flag [2] =1 ; printf ("#pins_per_row = %i\n", print_info- >pins_per_row) ; if (strcmp (pname,"pins per column\n") ==0) {print_info->pins_per_column=atoi (number) ; flag [3] =1 ; printf ("#pins_per_column = %i\n", print_info->pins_per_column) ;

if (strcmp (pname,"spot diameter\n") ==0) {print_info->spot_diameter=atof (number) ; flag [4] =1 ; printf ("#spot-dimaeter = %f\n", print_info->spot_diameter) ; if (strcmp (pname,"spot pitch\n") ==0) {print_info->spot_pitch=atof (number) ; flag [5] =1 ; printf ("#spot_pitch = %f\n", printinfo->spotpitch) ; if (strcmp (pname,"pin pitch rows\n") ==0) print_info->Pin_pitch_row=atof (number) ; flag [6] =1 ; printf ("#pin_pitch_row = %f\n", print_info->pin_pitch_row) ; } if (strcmp (pname,"pin pitch columns\n") ==0) {print_into->pin_pitch_column=atof (number) ; flag [7] =1 ; printf ("#pin_pitch_column = %f\n", print_info->pin_pitch_column);

/* Space to add new entries */ if (strcmp (pname, "pin rattle\n") ==0) {printinfo->pinrattle=atof (number) ; flag [11] =1 ; printf ("#pin_rattle = %'f\n", printinfo->pinrattle) ; if (strcmp (pname,"origin row\n") ==0) {print_info->origin_row=atoi (number) ; flag [12] =1 ; printf ("#origin_row = %i\n", print_info->origin_row) ; if (strcmp (pname,"origin column\n") ==0) {print_info->origin_column=aatoi (number) ; flag [13] =1 ; printf ("#origin_column = %i\n", printinfo->origincolumn) ; if (strcmp (pname,"ax\n") ==0) {print_info->ax=atof (number) ; flag [14] =1 ;

printf ("#ax = %f\n", print_info->ax) ; if (strcmp (pname,"ay\n") ==0) print_info->ay=atof (number) ; flag [15] =1 ; printf ("&num ay = %f\n", print_into->ay) ; if (strcmp (pname,"bx\n") ==0) {print_info->bx=atof (number) ; flag [16] =1 ; printf ("#bx = %f\n", prin_info->bx) ; if (strcmp (pname,"by\n") ==0) {print_info->by=atof (number) ; flag [17] =1 ; printf ("&num by = %f\n", print_into->by) ; if (strcmp (pname,"cx\n") ==0) print_info->cx=atof (number) ; flag [18]=1 ; printf ("#cx = %f\n", print_ionfo->cx) ; if (strcmp (pname,"cy\n") ==0)

{printinfo->cy=atof (number) ; flag [19] =l ; printf ("#cy = %f\n", print_info->cy) ; if (strcmp (pname,"dx\n") ==0) {print_info->dx=atof (number) ; flag [20] =1 ; printf ("#dx = %f\n", print_info->dx) ; if (strcmp (pname,"dy\n") ==0) print_info->dy=atof (number) ; flag [21] =1 ; printf ("&num dy = %f\n", print_info->by) ; if (strcmp (pname,"hexagonal\n") ==0) if ( (atoi (number) > (-l)) && (atoi (number) <5)) print_info->hexagonal=atoi (number) ; flag [22] =1 ; if (print-info->hexagonal==0) printf ("#rectangular grid type spceified... \n") ; else

printf ("#hexagonal grid type %i specified... \n", print_info->hexagonal) ; else printf ("#Warning, hexagonal type specifier is out of range... \n") ; } while (feof (printer-file) ==0) ; if (flag [0] ==0) {printf ("Error, printer file missing spots per row... \n") ; er=l ; if (flag [l] ==0) {printf ("Error, printer file missing spots per column... \n") ; er=l ; if (flag [2] ==0) {printf ("Error, printer file missing pins per row... \n") ; er=l ;

if (flag [3] ==0) {printf ("Error, printer file missing pins per column... \n") ; er=l ; if (flag [4] ==0) printf ("Error, printer file missing spot diameter... \n") ; er=l ; } if (flag [5] ==0) {if ((flag [14] ==0) && (flag [17] ==0)) {printf ("Error, printer file missing all spot pitch information... \n") ; er=l ; if ((flag [14] ==0) && (flag [17]) ==1) {printinfo->spotpitch=printinfo->by ; print-info->ax=print-info->by ; printf ("Warning spot pitch and ax assigned based on by... \n") ; if. ((flag[14] ==1) && (flag [17] ==0)) print-info->spot_pitch=print-info->ax ; print_info->by=print_info->ax ;

printf ("Warning spot pitch and by assigned based on ax... \n") ; if ((flag[14] ==1) && (flag [17] ==l)) {printinfo->spotpitch=0. 5* (print_info->ax + print_info->by) ; printf ("Warning spot pitch assigned based on ax and by... \n") ; } if (flag [5] ==1) {if ((flag[14] ==0) ## (flag[17] ==0)) print_info->ax=print_info->spot_pitch ; print_info->ax=print_info->spot_pitch ; } if (flag [15] ==0) print_info->ay=0. 0 ; if (flag [16] ==0) print_info->bx=0. 0 ; if ((flag[6] ==0) && flag [21] ==0) {printf ("Error, printer file missing pin pitch row... \n") ; er=l ; if ((flag [6] ==1) && flag [21] ==0) {printinfo->dy=printinfo->pinpitchrow ;

printf ("Warning dy assigned based on pin pitch row... \n") ; if ( (flag [6] ==0) && flag [21] ==1) {printinfo->pinpitchrow=printinfo->dy ; printf ("Warning pin pitch row assigned based on dy... \n") ; if (flag [20] ==0) print_info->dx=0. 0 ; if ((flag [7] ==0) && (flag [18] ==0)) prints ("Error, printer file missing pin pitch column... \n") ; er=l ; } if (flag[7] ==1) && (flag [18] ==0)) {printinfo->cx=printinfo->pinpitchcolumn ; printf ("Warning cx assigned based on pin pitch column... \n") ; if ((flag[7] ==0) && (flag [18] ==1)) {print_info->pin_pitch_column=print_info->cx ; printf ("Warning pin pitch column assigned based on cx... \n") ; if (flag [19] ==0)

print_info->cy=0. 0 ; /* if (flag [9] ==0) if (flag [10] ==0) if (flag [ll] ==0) {printf ("Warning printer file missing pin rattle... \n") ; print_info->pin_rattle=0.5*print_info->spot_pitch ; } if ((flag[12]==0) && (flag [13] ==0)) printinfo->docoarse=l ; else printinfo->docoarse=0 ; if (flag [12] ==0) {printf ("No origin row specified... \n") ; printinfo->originrow=0 ; } if (flag [13] ==0) {printf ("No origin column specified... \n") ; print-info->origin-column=0 ;

if (flag[22] ==1) {if ((flag[16] ==0) && (flag[17] ==0)) if ((print_info->hexagonal==1) ## (print_info->hexagonal==2)) {printinfo->bx=0. 5*printinfo->spotpitch ; print_info->by=0. 5*sqrt (3. 0) *print_info->spot_pitch ; printf ("#Warning bx set to %f\n", printinfo->bx) ; printf ("#Warning by set to %f\n", print_info->by) ; if ((flag[14] ==0) && (flag [15] ==0)) if((print_info->hexagonal==3) ##<BR> (print_info->hexagonal==4)) print_info->ax=0. 5*sqrt (3. 0) *print_info->spot_pitch ; print_info->ay=0. 5*printinfo->spotpitch ; printf ("#Warning ax set to %f\n", print_info->ax) ; printf ("#Warning ay set to %f\n", print_info->ay) ; else

{printinfo->hexagonal=0 ; printf ("#rectangular grid assumed... \n") ; if (er==l) {printf ("Fix errors in printer file... \n") ; exit (-l) ; free (pname) ; free (number) ; remove overlapping boxes. c &num include"defs. h" int remove compare column (const void. *c, const void *d) {struct box *a, *b ; a= ( (struct box *) c) ; b= ( (struct box *) d) ; if (a [0]. boxcolumn>b [0]. boxcolumn)

return (0) ; return (l) ; int remove compare row (const void *c, const void *d) {struct box *a, *b ; a= ( (struct box *) c) ; b= ( (struct box *) d) ; if (a [0]. boxrow>b [0]. boxrow) return (0) ; return (l) ; void writeboxpairinfo (struct box * removed, struct box * kept, struct quality_params * qparams) { printf ("removing %i %i %lf %lf\n", removed ->spot_row+1, removed->spot_column+l, quality (removed, qparams), removed->boxdistancefromgrid) ; printf ("keeping %i %i %lf %lf\n\n", kept->spot_row+1, kept->spotcolumn+l,

quality (kept, qparams), kept->boxdistancefromgrid) ; void write_box_info (struct box * removed, struct quality_params * qparams) printf ("removing W lf klf klf %lf\n\n", removed->spot_row+1, removed->spot_column+l, removed->box. average, removed->background. average, quality (removed, qparams), removed->boxdistancefromgrid) ; int remove_boxes (struct box * sl, struct box * s2, struct printer * p, struct quality_params * qparams) int number=0 ; /* if either have negative S-B remove them */ if ( (sl->box. average-s2->background. average) <0. 0) if ((sl->box_type==IN_GRID) && (sl->box_distance_from_grid >0)) {

number++ ; sl->boxtype=NOTINGRID ; writeboxinfo (sl, qparams) ; } if ( (s2->box. average-s2->background. average) <0. 0) if ((s2->box_type==IN_GRID) && (s2->box_distance_from_grid) >0)) number++ ; s2->boxtype=NOTINGRID ; write box-info (s2, qparams) ; } /* remove the lowest quality spot unless it is on the grid and not much lower quality, then remove the other spot */ if ((quality(s1, qparams) >quality (s2, qparams))) if (s2->boxtype==INGRID)

if (s2->boxdistancefromgrid>0. 0) number++ ; s2->boxtype=NOTINGRID ; writeboxpairinfo (s2, sl, qparams) ; else if (quality (sl, qparams) < (2. 0*quality (s2, qparams))) { if ((s1->box_type==IN_GRID)&&(s1->box_distance_from_grid >0. 0)) number++ ; sl->boxtype=NOTINGRID ; write_box_pair_info(s1, s2, qparams) ; } else if (s1->box_type==IN_GRID) { if (sl->boxdistancefromgrid>0) number++ ; sl->boxtype=NOTINGRID ;

write box pair-info (sl, s2, qparams) ; else if (quality (s2, qparams) < (2. 0*quality (s1, qparams))) { if ((S2->box_type==IN_GRID) && (s2->boxdistancefromgrid >0. 0)) { number++ ; s2->boxtype=NOTINGRID ; writeboxpairinfo (s2, sl, qparams) ; } } return (number) ; } int remove overlapping boxes (struct box *s, int n, struct printer *p, struct quality params * qparams)

{int i, <BR> J.<BR> <P> *k, done, numremoved ; double xdistance, ydistance ; k= (int *) malloc (sizeof (int) *n) ; numremoved = 0 ; for (i=o ; i<n ; i++) k [i] =i ; /* First sort the list by s. spot-column into ascending order. */ printf ("sorting... \n") ; hsort (s, k, n, sizeof (struct box), remove, compare column) ; printf ("Doing x... \n") ; for (i=0 ; i< (n-l) ; i++) done=0 ; for (j=i+l ; (j<n) && (done!=1) ; j++)

xdistance = (double) (s [k [j]].box_column-s[k[i]].boxcolumn) ; ydistance = fabs ( (double) (s [k [j]]. box_row-s [k [i]]. box_row)) ; if ((xdistance<p[0]. spot_pitch) && (xdistance>0. 0) && (ydistance< (p [0]. spot_pitch/2.0))) { done++ ; if (xdistance< (p [0]. spot_pitch-2. 0*p [0]. pin rattle)) numremoved+=removeboxes (&s [k [i]], &s [k [j]], p, qparams) ; } printf ("Sorting... \n") ; hsort (s, k, n, sizeof (struct box), remove-compare row) ; printf ("Doing y... \n") ; for (i=0 ; i< (n-l) ; i++)

done=0 ; for (j=i+l ; (j<n) && (done ! =l) ; j++) ydistance = (double) (s [k [j]]. box_row-s [k [i]]. box-row) ; xdistance = fabs ( (double) (s [k [j]]. box_Column-s [k [i]]. box_column)) ; if ( (ydistance< (p [0]. spot_pitch) && (ydistance>0. 0) && (xdistance< (p [0]. spot_pitch/2. 0))) done++ ; if (ydistance< (p [0]. spot_pitch-2, 0*p [0]. pin_rattle)) numremoved+=removeboxes (&s [k [i]], &s [k [j]], p, qparams) ; printf ("removed i boxes out of % i in remove_overlapping_boxes\n",num_remkoved, n) ; return (numremoved) ;

set-parameters. c #include "defs.h" void parameter-check (struct image-data * image, struct parameters * allparams) {double xl, yl ; struct printer *p ; p=&all_params->printer_info ; /* make sure the spots fit on the image */ get_xyfromspotandpin ((double) (p->pins_per_row-l), (double) (p->pinspercolumn-l), (double) (p->spots_per_row-1), (double) <BR> <BR> <BR> (p->spots_per_column-l),<BR> <BR> <BR> p, &xl, &yl) ; if (((int) (X1+p->spot_pitch+0. 5)) >image->width) {printf ("image width too small for printer parameters\n") ; exit (-l) ; } if (((int) (y1+p->spot_pitch+0.5)) >image->height)

{printf ("image height too small for printer parameters\n") ; exit (-l) ; /* make sure subgrids do not overlap */ if (p->pinsperrow>l) {get xyfromspotandpin (0. 0, 0. 0, (double) (p->spotsperrow-l), 0. 0, p, &xl, &yl) ; if ( ( (int) (xl+0. 5)) > p->pinpitchcolumn) {printf ("subgrids overlap by column with current printer parameters\n") ; exit (-l) ; if (p->spotspercolumn>l) {getxyfromspotandpin (0. 0, 0. 0, 0. 0, (double) (p->spotspercolumn-l), p, &xl, &yl) ; if ( ( (int) (yl+0. 5)) > p->pinpitchrow) {printf ("subgrids overlap by row with current printer parameters\n") ; exit (0) ; if (all_params_>background,.background_frame_width<1)

all_params->background.background_frame_width=1; if (all_params->crop_image_data.shift_flag==0) all_params->output_flags.row_shift=0 ; all_params->output_flags. col-shift=0 ; void set-statistics-flags, defaults (struct statistics flags * f) f->average=l ; f->stddev=l ; f->median=l ; f->average_one_sd=l ; f->average_two-sd=1 ; f->area=l ; f->area_one_sd=1 ; f->area_two_sd=1 ; f->area_zero=1 ; f->area saturated=l ; f->min=l ; f->max=l ; }

void set_output_flag_defaults (struct output data * f) f->output_path="#"; set_statisticsflags_defaults(&f->region); set statistics flags defaults (&f->spot) ; set_statistics_flags_defaults( &f->background ); set_statistics_flags_defaults( &f->ratio_common ); set_statistics_flags_defaults( &f->region_common ); set_statistics_flags_defaults( &f->spot_common ); set statisticsflagsdefaults (&f->backgroundcommon ) ; set_statistics_flags_defaults( &f->ratiowrt reference) ; set-statistics-flags-defaults ( &f->regionwrtreference) ; set_statistics_flags_defaults( &f->spot_wrt_reference ) i <BR> <BR> <BR> <BR> set-statistics_flags_defaults (<BR> <BR> <BR> <BR> &f->backgroundwrtreference) ;<BR> <BR> <BR> <BR> <BR> set statisticsflagsdefaults (&f->regionreference ) ; set_statistics_flags_defaults( &f->spot_reference ) ; set-statistics-flags defaults ( &f->backgroundreference) ; f->background_flag=1 ; f->spot_flag=l ; f->region_flag=l ;

f->ratio_common_flag=1 ; f->backgroundcommonflag=l ; f->spotcommonflag=l ; f->region_common_flag=1 ; f->ratio-wrt_reference_flag=1 ; f->backgroundwrtreferenceflag=l ; f->spot_wrt_reference_flag=1 ; f->ratio_wrt_reference_flag=1 ; f->background_reference_falg=1 ; f->spot_referenxce_flag=1 ; f->region_referenxce_flag=1 ; f->box_column=1 ; f->box_row=1 ; f->pin_row=l ; f->pin_column=1 ; f->spot_row=1 ; f->spotcolumn=l ; f->spot_number=1 ; f->spot_type=1 ; f->spot_perimeter=1 ; f->spot_width=1 ; f->spot_height=l ; f->numspots=0 ; f->spot_xbar=1 ; f->spot_ybar=1 ; f->spot_rbar=1 ; f->spot_rmin=1 ;

f->spotrmax=l ; f->spot distancefromgrid=l ; f->distance_from_spot_to_box=1 ; f->boxdistancefromgrid=l ; f->rowshift=0 ; f->colshift=0 ; f->grid_row=1 ; f->grid_column=1 ; f->box_dist_toi_grid=1 ; f->spot_dist_to_grid=1 ; f->slope=l ; f->intercept=l ; f->R=l ; f->geneid=0 ; } void set-parameter defaults (char *fname, struct parameters * all_params) {int i, num_spots ; /* first read in the printer information using the old read-printer-info routine */ read_printer_info (& all_params->printer_info, fname) ; all_p[arams->printer_info. axp=NULL ; all_params->printer_info. ayp=NULL ; allparams->printerinfo. bxp=NULL ;

all_params->printer_info. byp=NULL ; allparams->printerinfo. subgridvectorization=0 ; allparams->printerinfo. includemissing=0 ; /* now do a simple setup of parameters based on printer-info and command-line*/ /*furcation parameters*/ all_params->find_boxes. fraction_by_furcation=0. 0 ; allparams->findboxes. centertolerance=1. 5 ; /*others set to defaults*/ all_params->find boxes. limit-furcation=3 ; allparams->findboxes. limitcenter=6 ; allparams->findboxes. spotparams. cropwidth= (int) (2. 0 *all-params->printer_info.spot_pitch/3. 0) +1 ; all_params->find_boxes.spot_params.cro_height= (int) (2.

0*all params->printer-info. spot_pitch/3. 0) +1 ; all_paras->find_boxes.spot_params.fraction_Ibar=1. 0 ; all_params->find_boxes.spot_params.estimated_spot_area= 0. 25*M_PI*all_params->printer_info.spot_diameter*all_pa rams->printer_info. spot_diamketer ; all_params->find_boxes.spot_params.furcation_type+EDGER EJECTHOLEFILL ;

all_params->find_boxes. fast_flag=0 ; /*crop_image_data parameters*/ all_params->crop_image_data. spot_params. crop_width= (int ) (all params->printer-info. spot_pitch/2. 0) +1 ; all_params->crop_image_data. spot_params. crop_height= (in t) (all_params->printer_info.spot_pitch/2. 0) +l ; <BR> <BR> all_params->crop_image_data. spot_params. fraction-Ibar=l . 0 ; all_params->crop_image_data,.spot_params.estimat ed_spot area=0. 25*MPI*allparams->printerinfo. spotdiameter*a 11)_params->printer_info. spot diameter ; all_params->crop_image_data.spot_params.furcation_type= EDGEREJECTHOLEFILL ; /* background radius defined by spot_pitch from printer-file */ allparams->background. maskflag=0 ; allparams->background. backgroundradius= (int) (all_para ms->printer_info. spot_pitch/2. 0) ;

all_params->background. background width=all_params->backgrc all_params->background. backgroundheight=allparams->ba ckground. background-radius ; allparams->background. backgroundframewidth=l ; /* integration radius defined by spot_pitch */ all_params->integration. mask-flag=0 ; all_params->integration. mask-file_flag=0 ; all params->integration. square_flag=l ; all params->integration. circle-flag=0 ; allparams->integration. integrationwidth= (int) (0. 5* (all_params->printer_info.spot_pitch-1)) ; all_params->integration. integration_height= (int) (0. 5* (all_params->printer_info. spot_pitch-1)) ; all_params->integration. integration_radius= (int) (0. 5* (all_params->printer_info.spot_pitch-1)) ; /* integration small radius defined by spot diameter */ allparams->integrationsmall. maskflag=0 ; all_params->integration_small. mask file flag=0 ; _ all_params->integration_small.square_flag=1 ; allparams->integrationsmall. circleflag=0 ; all_params->integration-small. integration width= (int) (0. 25* (all_params->printer_info.spot_pitch+all_params_> printer-info. spot_diameter)) ;

allparams->integrationsmall. integrationheight= (int) (0. 25* (allparams->printerinfo. spot_pitch+all_params_> printer_info.spot_diameter)) ; all_params->integration_small.integration_radius= (int) # (0. 25* (all_params->printer_info.spot_pitch+all_params-> printer-info. spot_diameter)) ; /* integration output radius defined by printer box-size entry */ allparams->integrationout. maskflag=0 ; all_params->integration out. mask-file-flag=0 ; allparams->integrationout. squareflag=l ; allparams->integrationout. circleflag=0 ; allparams->integrationout. integrationwidth= (int) (0. 5* (allparams->printerinfo. spot-pitch-l)) ; allparams->integrationout. integrationheight= (int) (0. 5* (all_params->printer_info.spot_pitch-1)) ; allparams->integrationout. integrationradius= (int) (0. 5* (all_params->printer_infio.spot_pitch-1)) ; /*map spots parameters*/ all_params->map_spots. debug=0 ; <BR> <BR> all_params->map_spots. do_coarse=all_params->printer-inf o. do-coarse ; all_params->map_spots.do_fine=0 ;

all_params_>map_spots. do_coarse_pin_by_pin=1 ; all_params->map_spots.do_fine_pin_by_pin=1 ; all_params->map_spots.dio_distance=1 ; all_params->map-spots.increment_coarse= (int) (0. 5* (all params->printer-info. spot_pitch)) ; all_params->map_spots. increment-fine=1 ; all_params-<map_spots.range_fine_row= (int) (0. 25* (all_params->printer_info.spot_pitch)) ; all_params->map_spots.range_fine_column= (int) (0. 25* (all_params->printer_info.spot_pitch)) ; all_params->map_spots. incrementcoarsepinbypin= (int) (0. 25* (all_params->printer_info. spot_pitch)) ; all_params->map_spots. rangecoarsepinbypinrow= (int) (1. 0* (allparams->printerinfo. spotpitch)) ; all_params->map_spots. range_coarse_pin_by_pin_column= (i nt) (1. 0* (all-params->printer-info. spot pitch)) ; <BR> <BR> all_params->map_spots. rangecoarsepinbypin. rowautos elect=l ; all_params->map_spots.range_coarse_pin_by_pin_col_autos elect=l ;

all_params->map_spots. incrementfinepinbypin=l ; allparams->mapspots. rangefinepinbypinrow= (int) (0. 25* (all_params->printer_info. spot_pitch)) ; all_params->map_spots. rangefinepinbypincolumn= (int ) (0. 25* (all_params->printer_info.spot_pitch)) ; all_params->map_spots.incremkent_distance=1 ; all_params->map_spots.range_distance_row= (int) (0. 5* (all_params->printer_info.spot_pitch)) ; all_params->map-spots.range_distance_column= (int) (0. 5* (all params->printer-info. spot_pitch)) ; all_params->map_spots.snap-negatives_to_grid=0 ; /*find angles*/ all_params->find_angles.do_find_angles=1 ; allparams->findangles. xvectortolerance=0. 3* (all_par ams->printer_info- spot_pitch) ; allparams->findangles. yvectortolerance=0. 3* (all-par ams->printer_info. spot-pitch) ; all_params->find_angles.iteration_limit=10 ; allparams->findangles. convergencedistance=0. 00001 ; /* set output image flags */ all_params->output_image. tiff_zip_flag=0 ; all_params->output_image.tiff_jpg_flag=0 ;

all_params->output_image. jpg_flag=0 ; all_params->output_image. ppm_flag=1 ; allparams->outputimage. jpgquality=75 ; all_params->output_image.grid_flag=1 ; all-params->output-image. region flag=1 ; all_params->output_image. background_flag=l ; all_params->output_image. perimeter-flag=1 ; allparams->outputimage. integratedflag=0 ; allparams->outputimage. outputpath="." ; /* spot-by-spot shift params */ allparams->cropimagedata. shiftflag=0 ; all_params->crop_image_data.shift_range_row=3 ; all_params->crop_image_data.shift_range_column=3 ; all_params->printer_info.do_align=0 ; all_params->printer_info.do_interpolate=1 ; /* output flags */ set_output_flag_defaults(&all_params->output_flags) ; /* spot type settings */ /* Set the number of spot types and get memory for arrays */

allparams->printerinfo. spottypes. numberoftypes=7 ; all_params->printer_info. spot_types. type_name= (char **) malloc (sizeof (char *) *all_params->printer_info.spot_type.number_of_types) if (all_params->printer_info. spot_types. type name==NULL) {printf ("Failed malloc for all_params->printer_info. spot_types.type_anem in set_parameter defaults... \n") ; exit (-l) ; } all_params->printer-info. spot_types. number= (int *) malloc (sizeof (int) *all_params->printer_info. spot types. number of types) ; if (allparams->printerinfo. spottypes. number==NULL) {printf ("Failed malloc for allparams->printerinfo. spot types. number in setparametersdefaults... \n") ; exit (-l) ; for (i=0 ; i<all_params->printer_info.spot_types.number_of_types ; i++)

{ all_params->printer_info. spot_types.type name [i] = (char *) malloc (sizeof (char) *getpagesize ()) ; if ( <BR> <BR> <BR> <BR> <BR> allparams->printerinfo. spottypes. typename [i] ==NULL) {printf ("Failed malloc for allparams->printerinfo. spottypes. typename [i] in set_parameter_defaults...\n") ; exit (-1); } allparams->printerinfo. spottypes. number [i] =0 ; /* Set the spot type names */ all_params->printer_info.spot_types.type_name [REGULAR] = "REGULAR" ; allparams->printerinfo. spottypes. typename [POSITIVE] ="POSITIVE" ; allparams->printerinfo. spottypes. typename [NEGATIVE] ="NEGATIVE" ; all_params->printer_info.spot_types.type_name [EMPTY] = "E MPTY" ;

all-params->printer-info. spot-types. type-name [MISSING] ="MIS allparams->printerinfo. spottypes. typename [APPARITIO N] = "APPARITION" ; all_params->printer_info. spot_types.type_name [FLOOD] ="F LOOD" ; /* By default, set all spots to be of regular type and set the number of regular spots to be the total number of possible spots */ allparams->printerinfo. spottypes. number [REGULAR] = all_params->printer_info. pinsperrow*allparams->print er-info. pins_per_column* allparams->printerinfo. spotsperrow*allparams->prin ter-info. spots_per_column ; allparams->printerinfo. spottype= (int *) malloc (sizeof (int) *allparams->printerinfo. spot types. number [REGULAR]) ; if (all_params->printer_info. spot_type==NULL)

{printf ("Failed malloc for all_params->printer-info. spot_type in setparameterdefaults... \n") ; exit (-l) ; for (i=0 ; i<all_params->printer-info. spot-types. number [REGULAR] ; i++) all_params->printer_info. spot_type [i] =REGULAR ; /* By default, the spot type file name should be empty */ allparams->printerinfo. spot types. filename=NULL ; /* allocate space for the gene ids*/ numspots = all_params->printer_info. pins_per_row* allparams->printerinfo. pinspercolumn*<BR> allparams->printerinfo. spotsperrow* allparams->printerinfo. spotspercolumn ; all_params->printer_info. gene id= (char **) malloc (numspots*sizeof (char *)) ; if (allparams->printerinfo. gene_id==NULL) printf ("failed malloc for gene id in set_parameters\n") ; else /*set all the pointers to gene id info to NULL*/

for (i=0 ; i<numspots ; i++) all_params->printer_info.gene_id [i] =NULL ; all_params->printer_info. gene_id_column_headings=NULL ; /* Read in any user set parameters from the printer file */ read_parameters (all_params, fname) ; all_params->integration. integrationheight=allparams-> integration. integration-radius ; all_params->integration.integration_width =allparams->integration. integration radius ; get_integration_info (&all_params->integration) ; get_integration_info (&allparams->integrationout) ; get_background_mask(&all-params->background) ; sort. c #include "defs. h" int pixel-sort-compare (const void *c,

const void *d) {unsigned short int *a, *b ; a= ( (unsigned short int *) c) ; b= ( (unsigned short int *) d) ; if (a [0]>b[0]) return (. 1) ; return (0) ; int double-sort-compare (const void *c, const void *d) {double *a, *b ; a= ((double *) c) ; b= ((double *) d) ; if (a [0] >b [0]) return (l) ; return (0) ; int data-sort-compare (const void *c, const void *d)

{struct box *a, *b ; a= ( (struct box *) c) ; b= ( (struct box *) d) ; if ((a[0].box_type==NOT_IN_GRID) && (b [0]. boxtype==NOTINGRID)) return (l) ; if ((a[0].box_type ! =NOT_IN_GRID) && (b [0]. boxtype==NOTINGRID)) return (l) ; if ((a[0].box_type==NOT_IN_GRID) && (b [0]. box-type ! = NOT_IN_GRID)) return (0) ; if ((a[0].box_type==NOT_IN_GRID) && (b [0]. box_type==NOT_IN_GRID) {if (a [0]. pinrow<b [0]. pinrow) return (l) ; if (a [0]. pinrow==b [0]. pin row) {if (a [0]. pincolumn<b [0]. pincolumn) return (1) ; if (a [0]. pincolumn==b [0]. pincolumn) {if (a [0]. spotrow<b [0]. spotrow)

return (l) ; if (a [0]. spot_row==b [0]. spot_row) {if (a [0]. spot_column<b[0].spot_column) return (l) ; return (0) ; void hsort (void *va, int *p, int n, int size, int (*compare) (const void *, const void *)) {int i, ir, j, 1, *pa, temp ; pa=p-1 ; if (n<2) return ; 1= (n >> 1) +1 ; ir=n ; for ( ; ;) if (1>1) {1=1-1 ;

temp=pa [l] ; else {temp=pa [ir] ; pa [ir]=pa[1] ; ir=ir-l ; if (ir==1) {pa [l] =temp ; break ; } i=l; j=l+l; while (j <= ir) {if ((j < ir) && (compare (((char *) va) +pa [j] *size/sizeof (char), ((char *) va) +pa [j+1] *size/sizeof (char)) ==1)) j++ ; if (compare (((char *) va) +temp*size/sizeof (char), ((char *) va) +pa [j] *size/sizeof (char)) ==l) {pa [i] =pa [j] ; i=j ; <<= 1 ; } else j=ir+l ;

pa [i] =temp ; void double_hsort (double *va, int *p, int n) {int i, ir, j, 1, *pa, temp ; pa=p-l ; if (n<2) return ; l= (n >> 1) +1 ; ir=n ; for ( ; ;) if (1>1) {1=1-1 ; temp=pa [l] ; else {temp=pa[ir] ; pa [ir]=pa[1] ; ir=ir-1 ; if (ir==1) {pa [1] =temp ;

break ; } } i=l ; j=1+1 ; while (j <= ir) {if ( (j < ir) && (va [pa [j]] >va [pa [j+l]])) j++ ; if (( va[temp]>va [pa [j]])) i=J ; i=j; j <<= 1; <BR> <BR> }<BR> else j=ir+1; pa [i] =temp ; #define M 7 #define NSTACK 51 void qsort double (double *va, int *p, int n) {int i, a, ir=n,<BR> il

k, <BR> 1=1,<BR> jstack=0, temp, istack [NSTACK], *pa ; pa=p-l ; for (;;) { if (ir-1 < M) { for (j=l+1 ; j<=ir ; j++) { a=pa [j] ; for (i=j-1 ; i>=l ; i--) { if (va [pa [i]] >= va [a]) break ; pa [i+1]=pa[i] ; pa [i+l] =a ; } if (jstack==0) break ; ir=istack [jstack--] ; 1=istack [jstack--] ; else { k= (l+ir) >> 1; temp=pa [k] ; pa [k] =pa [l+l] ; pa [l+l] =temp ;

if (va [pa [l]] < va [pa [ir]]) {temp=pa [l] ; pa [l]=pa[ir] ; pa [ir] =temp ; if (va [pa [1+1]] < va [pa [ir]]) {temp=pa [l+1] ; pa[l+1]=pa[ir] ; pa [ir] =temp ; if (va [pa [l]] < va [pa [l+1]]) {temp=pa [l] ; pa [l]=pa[l+1] ; pa [l+l] =temp ; } i=l+1; j=ir ; a=pa [l+1] ; for ( ; ;) do i++ ; while (va [pa [i]] > va [a]) ; do j-- ; while (va [pa [jl] < va[a]) ; if (j < i) break ; temp=pa [i] ; pa [i] =pa [j] ; pa [j] =temp ;

pa [l+1] =pa [j] ; pa [j] =a ; jstack=jstack+2 ; if (jstack>NSTACK) {printf ("Stack too small in qsort... \n") ; exit (-l) ; if (ir-i+l >= j-1) { istack [jstack] =ir ; istack [jstack-l] =i ; ir=j-1 ; } else { istack [jstack]=j-1 ; istack [jstack-l] =l ; l=i ; } void qsort_integrated (Integrated *va, int *p, int n) {int i, a, ir=n, il k,

1=1,<BR> jstack=0, temp, istack [NSTACK], *pa ; pa=p-1 ; for ( ; ;) <BR> if (ir-l < M) {<BR> for (j=l+1 ; j<=ir ; j++) { a=pa [j] ; for (i=j-1 ; i>=l ; i--) { if (va [pa [i]] >= va [a]) break ; pa [i+l] =pa [i] ; pa [i+l] =a ; if (jstack==0) break ; ir=istack [jstack--] ; 1=istack [jstack--] ; else k= (l+ir) >> 1; temp=pa [k] ; pa [k] =pa [l+1] ; pa [l+l] =temp ;

if (va [pa [l]] < va [pa [ir]]) {temp=pa [l] ; pa [l]=pa[ir] ; pa [ir] =temp ; if (va [pa [l+1] < va [pa [ir]]) {temp=pa [l+1] ; pa [l+1]=pa[ir] ; pa [ir] =temp ; if (va [pa [l]] < va [pa [l+l]]) {temp=pa [l] ; pa [l] =pa [l+l] ; pa [.+1]=temp ; } j=ir ; a=pa [l+1] ; for ( ; ;) do i++ ; while (va [pa [i]] > va [a]) ; do j-- ; while (va [pa [j]] < va [a]) ; if (j < i) break ; temp=pa [i] ; pa [i] =pa [j] ; pa [j]=temp;

pa [l+1] =pa [j] ; pa [j] =a ; jstack=jstack+2 ; if (jstack>NSTACK) {printf ("Stack too small in qsort... \n") ; exit (-l) ; if (ir=i+1 >= j-l) istack [jstack] =ir ; istack [jstack-l] =i ; ir=j-l ; } else { istack [jstack] =j-l ; istack [jstack-l] =l ; l=i ; void qsort_unsigned_short_int (unsigned short int *va, int *p, int n) {int i, a, ir=n,

j, k, 1=1, jstack=0, istack [NSTACK], *pa ; unsigned short int temp ; pa=p-1 ; for (;;) { if (ir-l < M) {<BR> for (j=l+1 ; j<=ir ; j++) { a=pa [j] ; for (i=j-1 ; i>=l ; i--) { if (va [pa [i]] >= va [a]) break ; pa [i+l] =pa [i] ; pa [i+l] =a ; if (jstack==0) break ; ir=istack [jstack--] ; 1=istack [jstack--] ; } else { k= (l+ir) >> temp=pa [k] ;

pa [k] =pa [l+1]; pa [l+l] =temp ; if (va [pa [l]] < va [pa [ir]]) temp=pa [l] ; pa [l]=pa[ir] ; pa [ir] =temp ; if (va [pa [1+1]] < va [pa [ir]]) {temp=pa [l+1] ; pa [l+l] =pa [ir] ; pa [ir] =temp ; if (va [pa [l]] < va [pa [1+1]]) {temp=pa [l] ; pa [l]=pa[l+1] ; pa [l+l] =temp ; } j=ir ; a=pa [l+1] ; for ( ; ;) { do i++ ; while (va [pa [i]] > va [a]) ; do j-- ; while (va [pa [j]] < va [a]) ; if (j < i) break ; temp=pa [i] ;

pa [i] =pa [j] ; pa [j] =temp ; } pa [l+l] =pa [j] ; pa [j] =a ; jstack=jstack+2 ; if (jstack>NSTACK) {printf ("Stack too small in qsort... \n") ; exit (-l) ; if (ir-i+l >= j-1) { istack [jstack] =ir ; istack [jstack-l] =i ; ir=j-1 ; } else { istack [jstack]=j-1 ; istack [jstack-l] =l ; l=i ; spot type. c

#include"defs. h" int get-spot type (char type) if (type=='a') return (APPARITION) ; if (type=='n') return (NEGATIVE) ; if (type=='p') return (POSITIVE) ; if (type=='m') return (MISSING) ; if (type=='e') return (EMPTY) ; if (type=='f') return (FLOOD) ; return (REGULAR) ; int letters to numbers (char letters [2]) return (((int) letters [1])-65 + 26* ( ( (int) letters [0])-65) +1) ;

void set-spot-type (int pr, int pc, int sr, int sc, char type, struct printer * p) {int sn, st ; st=get_spot_type (type) ; if ((pr>(-1)) && (pr<=p[0].pins_per_column) && (pc> (-l)) && (pc<=p [0]. pins_per_row) && (sr> (-l)) && (sr<=p [0]. spots_per_column) && (sc> (-l)) && (sc<=p [0]. spots_per_row)) { /* A single spot */ if ((pr>0) && (pc>0) && (sr>0) && (sc>0)) {sn=get_spot_number(pr-1, pc-1, sr-1, sc-1, p) ; p [0]. spot_type [sn] =st ; /* All subgrids */ if ((pr==0) && (pc==0) && (sr==0) && (sc==0)) {for (pr=0 ; pr<p [0]. pins_per_column ; pr++) for (pc=0 ; pc<p [0]. pins_per_row ; pc++) for (sr=0 ; sr<p [0]. spots_per_column ; sr++) for (sc=0 ; sc<p [0]. spots_per_row ; sc++) {sn=getspotnumber (pr, pc, sr, sc, p) ; p [0]. spot_type [sn] =st ; pr=0 ;

pc=0 ; sr=0 ; sc=0 ; /* Threesee's */ if ((pr==0) && (pc==0) && (sr==0) && (sc>0)) {for (pr=0 ; pr<p [0]. pins_per_column ; pr++) for (pc=0 ; pc<p [0]. pinsperrow ; pc++) for (sr=0 ; sr<p [0]. spotspercolumn ; sr++) sn=get_spot_number (pr, pc, sr, sc-1, p) ; p [0]. spot_type [sn] =st ; pr=0 ; pc=O ; sr=0 ; if ((pr==0) && (pc==0) && (sr>0) && (sc==0)) {for (pr=0 ; pr<p [0]. pins per-column ; pr++) for(pc=0 ; pc<p [0]. pinsperrow ; pc++) for (sc=0 ; sc<p [0]. spots per row ; sc++) {sn=getspotnumber (pr, pc, sr-1, sc, p) ; p [0]. spot_type [sn]=st ; pr=0 ; pc=0 ;

sc=0 ; if ((pr==0) && (pc>0) && (sr==0) && (sc==0)) {for (pr=0 ; pr<p [0]. pinspercolumn ; pr++) for (sr=0 ; sr<p [0]. spotspercolumn ; sr++) for (sc=0 ; sc<p [0]. spotsperrow ; sc++) {sn=get_spot_number (pr, pc-1, sr, sc, p) ; p[0].spot_type[sn]=st ; pr=0 ; sr=0 ; sc=O ; if ((pr>0) && (pc==0) && (sr==0) && (sc==0)) {for (pr=0 ; pr<p [0]. pins_per_column ; pr++) for (pc=0 ; pc<p [0]. pins per row ; pc++) for (sr=0 ; sr<p [0]. spotspercolumn ; sr++) for (sc=0 ; sc<p [0]. spots-per row ; sc++) {sn=get_spot_number(pr-1, pc, sr, sc, p) ; p [0]. spot_type[sn]=st ; pc=O ; sr=0 ; sc=O ;

/* Twosee's */ if ((pr>0) && (pc==0) && (sr>0) && (sc==0)) {for (pc=0 ; pc<p [0]. pins_per_row ; pc++) for (sc=0 ; sc<p [0]. spotsperrow ; sc++) {sn=getspotnumber (pr-l, pc, sr-1, sc, p) ; p [0]. spot_type[sn]=st ; pc=O ; sc=O ; if ((pr>0) && (pc==0) && (sr==0) && (sc>0)) {for (pc=0 ; pc<p [0]. pins per row ; pc++) for (sr=0 ; sr<p [0]. spotspercolumn ; sr++) {sn=getspotnumber (pr-l, pc, sr, sc-1, p) ; p [0]. spot_type [sn] =st ; 9 pC=0 ; sr=0 ; if ((pr>0) && (pc>0) && (sr==0) && (sc==0)) {for(sr=0 ; sr<p [0]. spots_per_column ; sr++) for (sc=0 ; sc<p [0]. spots_per_row ; sc++) {sn=getspotnumber (pr-l, pc-1, sr, sc, p) ; p [0]. spot_tyep[sn]=st ;

sr=0 ; sc=O ; if ((pr==0) && (pc>0) && (sr==0) && (sc>0)) {for (pr=0 ; pr<p [0]. pins_per_column ; pr++) for (sr=0 ; sr<p [0]. spotspercolumn ; sr++) {sn=getspotnumber (pr, pc-1, sr, sc-1, p) ; p [0]. spot_type [sn] =st ; } pr=0 ; sr=0 ; if ((pr==0) && (pc>0) && (sr>0) && (sc==0)) {for (pr=0 ; pr<p [0]. pinspercolumn ; pr++) for (sc=0 ; sc<p [0]. spots-per-row ; sc++) {sn=get_spot number (pr, pc-1, sr-1, sc, p) ; p [0]. spot_type[sn]=st ; pr=0 ; sc=0 ; if ((pr==0) && (pc==0) && (sr>0) && (sc>0)) {for (pr=0 ; pr<p [0]. pins per-column ; pr++) for (pc=0 ; pc<p [0]. pins-per row ; pc++) {sn=get_spot_number (pr, pc, sr-1, sc-1, p) ;

p [0]. spottype [sn] =st ; pr=0 ; pc=O ; /* A single subgrid column */ if ((pr>0) && (pc>0) && (sr>0) && (sc==0)) {for (sc. =0 ; sc<p [0]. spots-per row ; sc++) {sn=get_spot_number(pr-1, pc-1, sr-1, sc, p) ; p [0]. spot_type[sn]=st ; } sc=O ; /* A single subgrid row */ if ((pr>0) && (pc>0) && (sr==0) && (sc>0)) {for(sr=0 ; sr<p [0]. spots-per-column ; sr++) {sn=getspotnumber (pr-l, pc-1, sr, sc-1, p) ; p [0]. spot_type[sn]=st ; sr=0 ; /* A column of subgrids */ if ((pr>0) && (pc==0) && (sr>0) && (sc>0)) {for (pc=0 ; pc<p [0]. pins per row ; pc++)

{sn=getspotnumber (pr-l, pc, sr-1, sc-1, p) ; p [0]. spot_type [sn] =st ; pc=O ; /* A row of subgrid row */ if ((pr==0) && (pc>0) && (sr>0) && (sc>0)) " {for (pr=0 ; pr<p [0]. pins_ter_column ; pr++) {sn=getspotnumber (pr, pc-1, sr-1, sc-1, p) ; p [0]. spot_type[sn]=st ; pr=0 ; } #ifdef WET DOT void readspottypefile (struct printer *p) {FILE *f ; int sn, sr, sc, pr, pc, numread, numspots ; char type, s [15], s1 [3], s2 [3] ; num-spots=p [0]. spotsperrow*p [0]. spotspercolumn ; printf ("Reading spot type file %s for wet dot inspection... \n", p [0]. spot types. filename) ;

f= (FILE *) fopen (p [0]. spot-types.filename, "r") ; if (f==NULL) {printf ("Failed to open missing spot file %s in readmissingspotfile... \n", p [0]. spot_types. filename) ; exit (-l) ; pr=l ; pc=l ; do {num_read=fscanf(f, "%s %s %s", s, sl, s2) ; sr=atoi (s2) ; sc=p [0]. spotsperrow+l-letterstonumbers (sl) ; type= (char) s [0] ; if (numread==3) set_spot_type (pr, pc, sr, sc, type, p) ; while ( ! feof (f)) ; fclose (f) ; /* Count up the types */ for (sn=0 ; sn<p [0]. spot-types.number_of_types ; sn++) p [0]. spot types. number [sn] =0 ; for (sn=0 ; sn<num_spots ; sn++) p [0]. spot-types. number [p [0]. spot_type[sn]]++ ;

#else void readspottypefile (struct printer *p) {FILE *f ; int. sn, sr, sc, pr, pc, numread, numspots ; char type, s [15] ; num_spots=p[0].pins_per_row*p[0].pins_per_column*p[0]. s pots_per_row*p[0].spots_per_column ; printf ("Reading spot type file %s...\n", p [0]. spot_types. filename) ; f=fopen (p [0]. spot_types.filename, "r") ; if (f==NULL) {printf ("Failed to open missing spot file os in readmissingspotfile... \n", p [0]. spot-types. filename) ; exit (-l) ; do num_read=fscanf(f, "%s %i %i %i %i", s, &pr, &pc, &sr, &sc) ; type= (char) s [0] ; if (numread==5)

set_spot_type (pr, pc, sr, sc, type, p) ; while ( ! feof (f)) ; fclose (f) ; /* Count up the types */ for (sn=0 ; sn<p [0]. spot-types. number-of-types ; sn++) p [0]. spot-types. number [sn] =0 ; for (sn=0 ; sn<numspots ; sn++) p [0]. spot types. number [p [0]. spot_type[sn]]++ ; #endif void read spot types generic (struct printer *p, FILE * f) int sn, sr, sc, pr, pc, numread, numspots ; char type, s [15] ; char *line ; char *end="end\tspot type list\n" ; line= (char *) malloc (getpagesize () *sizeof (char)) ; if (line==NULL) {

printf ("failed malloc in read_spot_types_generic\n") ; return ; numspots=p [0]. pinsperrow*p [0]. pinspercolumn*p [0]. s potsperrow*p [0]. spotspercolumn ; fgets (line, getpagesize () *sizeof (char), f) ; while ( ( (strstr (line, end) ==NULL) && ( ! feof (f)) ) num_read=sscanf (line, "%s %i %i %i %i", s, &pr, &pc, &sr, &sc) ; type= (char) s [0] ; if (numread==5) set-spot type (pr, pc, sr, sc, type, p) ; fgets (line, getpagesize () *sizeof (char), f) ; /* Count up the types */ for (sn=0 ; sn<p [0]. spot types. number of types ; sn++) p [0].spot_types. number [sn]=0 ; for (sn=0 ; sn<numspots ; sn++) p [0]. spot types. number [p [0]. spot_type [sn]]++ ;

void readgeneidgeneric (struct printer *p, FILE * f) { int sr, sc, pr, pc, numread, numspots, i ; char *line ; char *id ; char *end="end\tgene id list\n" ; line= (char *) malloc (getpagesize () *sizeof (char)) ; if (line==NULL) { printf ("failed malloc in read_gene_id_generic\n") ; return ; } /*if memory has not already been allocated, try to do it*/ if (p->gene_id==NULL) numspots=p [0]. pinsperrow*p [0]. pinspercolumn*p [0]. s potsperrow*p [0]. spotspercolumn ; p->geneid= (char **) malloc (numspots*sizeof (char *)) ; if (p->gene_id==NULL) printf ("failed malloc in read_gene_id_generic\n") ; return ;

/*set all the pointers to NULL*/ for (i=0 ; i<numspots ; i++) p->geneid [i] =NULL ; } /*get the column headings*/ fgets (line, getpagesize () *sizeof (char), f) ; id = goto n strstr (line, 4,"\t") ; if (p->geneidcolumnheadings ! =NULL) free (p->geneidcolumnheadings) ; p->gene_id_column_headings=strdup (id+1) ; /*get the gene ids*/ fgets (line, getpagesize () *sizeof (char), f) ; while ( ( (strstr (line, end) ==NULL) && (!feof(f)) ) num_read=sscanf (line, "%i %i %i %i", &pr, &pc, &sr, &sc) ; if (numread==4) { id = goto n strstr (line, 4,"\t") ; if (id ! =NULL) set_gene_id_generic (pr, pc, sr, sc, id+1, p) ; fgets (line, getpagesize () *sizeof (char), f) ; void read_gene_id_corning (struct printer *p, FILE * f)

int sr, sc, pr, pc, numread, numspots, i ; char *line ; char *id ; char *end="end\tgene id list\n" ; char subgrid [5] ; line= (char *) malloc (getpagesize () *sizeof (char)) ; if (line==NULL) { printf ("failed malloc in read_gene_id_generic\n") ; return ; } /*if memory has not already been allocated, try to do it*/ if (p->gene_id==NULL) numspots=p [0]. pinsperrow*p [0]. pinspercolumn*p [0]. s potsperrow*p [0]. spotspercolumn ; p->gene_id= (char **) malloc (num-spots*sizeof (char *)) if (p->gene_id==NULL) printf ("failed malloc in read_gene_id_generic\n") ; return ; /*set all the pointers to NULL*/

for (i=0 ; i<numspots ; i++) p->geneid [i] =NULL ; /*get the column headings*/ fgets (line, getpagesize () *sizeof (char), f) ; id = goto n strstr (line, 3,"\t") ; if (p->geneidcolumnheadings ! =NULL) free (p->gene_id column headings) ; _<BR> p->geneidcolumnheadings=strdup (id+l) ; /*get the gene ids*/ fgets (line, getpagesize () *sizeof (char), f) ; while ( ( (strstr (line, end) ==NULL) && ( ! feof (f)) ) num_read=sscanf (line, "%s %i %i", subgrid, &sr, &sc) ; if (strlen (subgrid) >2) { printf ("Subgrid designations with more than two characters not supported\n") ; return ; pr= (toupper ( (int) subgrid [0])-64) ; pc=atoi (&subgrid [l]) ; if (nus { id = goto n-strstr (line, 3,"\t") ; if (id ! =NULL) set_gene_id_generic (pr, pc, sr, sc, id+1, p) ; fgets (line, getpagesize () *sizeof (char), f) ;

} void set_gene_id_generic (int pr, int pc, int sr, int sc, char *gene-id, struct printer * p) int sn ; if ((pr>(-1)) && (pr<=p[0].pins_per)_column) && (pc> (-1)) && (pc<=p [0]. pins_per_row) && (sr>(-1)) && (sr<=p[0].spots_per_column) && (so (-l)) && (sc<=p [0]. spotsperrow)) { sn=get_spot_number (pr-1, pc-1, sr-1, sc-1, p) ; if (p->gene_id ! =NULL) if (p->gene-id [sn] ! =NULL) free (p->gene-id [sn]) ; p->geneid [sn] =strdup (geneid) ; statistics. c #include"defs. h" void get-list-statistics (unsigned short int * list,

int n, struct statistics *s) {int i, *sd ; double sum_intensity, sum2-intensity ; if (n==0) { s [0]. area=0 ; s [0]. area_one_sd=0 ; s [0]. area_two_sd=0 ; s [0]. areazero=0 ; s [0]. areasaturated=0 ; s [0]. average=0. 0 ; s [0]. std dev=0. 0 ; s [0]. median=0. 0 ; s [0]. averageonesd=0. 0 ; s [0]. average_two_sd=0. 0 ; s [0]. min=0. 0 ; s [0]. max=0. 0 ; return ; else sum-intensity=0. 0 ; sum2_intensity=0. 0 ;

for (i=0 ; i<n ; i++) {sumintensity=sumintensity + ( (double) list [i]) ; sum2intensity=sum2intensity + ( (double) list [i]) * ( (double) list [i]) ; s [0]. area=n ; s [0]. average=sum_intensity/((double) s [0]. area) ; s [0]. std_dev=sqrt (sum2_intensity/((double) s [0]. area)-s [0]. average*s [0]. average) ; sd= (int *) malloc (sizeof (int) *n) ; if (sd==NULL) {printf ("Failed malloc in get-list-statistics... \n") ; exit (-l) ; } for (i=0 ; i<n ; i++) sd [i] =i ; qsortunsignedshortint (list, sd, n) ; if ( (n % 2) ==1) s [0]. median= ( (double) list [sd [(n/2)]]) ; else s [0]. median= ( (double) (list [sd [(n/2)]] + list [sd [n/2-1]])/2. 0) ; s->min= (double) (list [sd [n-l]]) ;

s->max= (double) (list [sd [0]]) ; s [0]. area zero=0 ; if (s->min==0) i=n-1 ; while (i>-l) {if (list [sd [i]] ==0) s->area_zero++ ; i-- ; else { i=-1 ; } s [0]. area_saturated=0 ; if (s->max==MAXINTENSITY) i=o ; while (i<n) if (list [sd [i]] ==MAX INTENSITY) {s->areasaturated++ ; i++ ; else {i=n ;

free (sd) ; s [0]. area one sd=0 ; s [0]. area two sd=0 ; s [0]. average one sd=0. 0 ; s [0]. average two sd=0. 0 ; for (i=0 ; i<n ; i++) { if((((double) list [i]) < (s [0]. average + s [0]. stddev)) && ( ( (double) list [i]) > (s [0]. average- s [0]. stddev))) {s [0]. area_one_sd++; s [0]. average_one_sd=s[0].average_one_sd + ((double) list [i]) ; if ( ( ( (double) list [i]) < (s [0]. average + 2. 0*s [0]. std dev)) && ( ( (double) list [i]) > (s [0]. average- 2. 0*s [0]. std dev))) {s [0]. area two sd++ ; s [0]. average_two_sd=s[0].average_two_sd + ( (double) list [i]) ; if (s [0]. area one sd ! =0) s [0]. average_one_sd=s[0].average_one_sd/((double) s [0]. area one sd) ;

if (s [0]. area_two_sd ! =0) s [0]. average_two_sd=s[0].average_two_sd/((double) s [03. area two sd) ; void get-list-statistics-fast (unsigned short int * list, int n, struct statistics *s) {int i ; double sum_intensity, sum2_intensity ; if (n==0) s [0]. area=0 ; s [0]. area one sd=0 ; s [0]. area two sd=0 ; s [0]. area zero=0 ; s [0]. area saturated=0 ; s [0]. average=0. 0 ; s [0]. std_dev=0. 0 ; s [0]. median=0. 0 ; s [0]. average_one_sd=0. 0 ; s [0]. average two-sd=0. 0 ;

s [0]. min=0. 0 ; s [0]. max=0. 0 ; return ; else sum_intensity=0. 0 ; sum2_intensity=0. 0 ; for (i=0 ; i<n ; i++) {sumintensity=sumintensity + ((double) list [i]) ; sum2-intensity=sum2-intensity + ( (double) list [i]) * ( (double) list [i]) ; } s [0]. area=n ; s [0]. average=sum_intensity/((double) s [0]. area) ; s [0]. std_dev=sqrt (sum2_intensity/((double) s [0]. area)-s [0]. average*s [0]. average) ; /*estimate median by average*/ s->median=s->average ; /*do not compute this stuff*/ s [0]. area zero=0 ; s [0]. area saturated=0 ;

s [0]. area_one_sd=0 ; s [0]. area_two_sd=0 ; s [0]. average one sd=0. 0 ; s [0]. average_two_sd=0. 0 ; s [0]. min=0. 0 ; s [0]. max=0. 0 ; } void getdliststatistics (double * list, int n, struct statistics *s) {int i, *sd ; double sum_intensity, sum2-intensity ; double * new-list ; if (n==0) s [0]. area=0 ; s [0]. area_one_sd=0 ; s [0]. area_two_sd=0 ; s [0]. area zero=0 ; s [0]. area saturated=0 ; s [0]. average=0. 0 ;

s [0]. std dev=0. 0 ; s [0]. median=0. 0 ; s [0]. average_one_sd=0. 0 ; s [0]. averagetwosd=0. 0 ; s [0]. min=0. 0 ; s [0]. max=0. 0 ; return ; else new-list= (double *) malloc (sizeof (double) *n) ; if (newlist==NULL) {printf ("Failed malloc in getliststatistics... \n") ; exit (-l) ; sum_intensity=0. 0 ; sum2_intensity=0. 0 ; s->area=0 ; s->areasaturated=0 ; s->areazero=0 ; for (i=0 ; i<n ; i++) { if ( (list [i] ==-DBLMAX)) s->areazero++ ;

else if (list [i] ==DBLMAX) s->areasaturated++ ; else new_list [s->area]=list [i] ; sumintensity=sumintensity + (list [i]) ; sum2intensity=sum2intensity + (list [i]) * (list [i]) ; s [0]. area++ ; } if (s->area>0) s [0]. average=sum_intensity/((double) s [0]. area) ; s [0]. std_dev=sqrt (sum2_intensity/((double) s [0]. area)-s [0]. average*s [0]. average) ; sd= (int *) malloc (sizeof (int) *s->area) ; if (sd==NULL) printf ("Failed malloc in get-list-statistics... \n") ; exit (-l) ; for (i=0 ; i<s->area ; i++) sd [i] =i ;

qsort_double (new_list, sd, s->area) ; if ((s->area % 2) ==1) s [0]. median= (new_list [sd[(s->area/2)]]) ; else s [0]. median= ((new_list [sd[(s->area/2)]] + new-list [sd [s->area/2-l]])/2. 0) ; s->min= (newlist [sd [s->area-l]]) ; s->max= (new_list [sd [0]]) ; free (sd) ; s [0]. areaonesd=0 ; s [0]. area two sd=0 ; s [0]. averageonesd=0. 0 ; s [0]. averagetwosd=0. 0 ; for (i=0 ; i<s->area ; i++) if (((new_list[i]) < (s [0]. average + s [0]. std dev)) && (( new_list [i]) > (s [0]. average- s [0]. std dev))) s [0]. area one sd++ ; s [0]. average_one_sd=s[0].average_one_sd + (newlist [i]) ; if ((( new_list [i]) < (s [0]. average + 2.0*s[0].std_dev)) &&

(( new_list [i]) > (s [0]. average- 2. 0*s [0]. std-dev) { s [0]. area two sd++ ; s [0]. average_two_sd=s[0].average_two_sd + (newlist [i]) ; if (s [0]. area_one_sd!=0) s [0]. average_one_sd=s[0].average_one_sd/((double) s [0]. area one sd) ; if (s [0]. area_two_sd!=0) s [0]. average_two_sd=s[0].average_two_sd/((double) s [0]. area two sd) ; else s [03. area one sd=0 ; s [0]. area_two_sd=0) ; s [0]. average=0. 0 ; s [0].std_dev=0. 0 ; s [0]. median=0. 0 ; s [0]. average one-sd=0. 0 ; s [0]. average two-sd=0. 0 ; s [0]. min=0. 0 ; s [0]. max=0. 0 ; }

free (new_list) ; void getdliststatisticsfast (double * list, int n, struct statistics *s) {int i ; double sum-intensity, sum2_intensity ; if (n==0) {s [0]. area=0 ; s [0]. area one sd=0 ; s [0]. area_two_sd=0 ; s [0]. area zero=0 ; s [0]. area_saturated=0 ; s [0]. average=0. 0 ; s [0]. std dev=0. 0 ; s [0]. median=0. 0 ; s [0]. average one-sd=0. 0 ; s [0]. average_two_sd=0. 0 ; s [0]. min=0. 0 ; s [0]. max=0. 0 ; return ; else {

sum-intensity=0. 0 ; sum2_intensity=0. 0 ; s->area=0 ; s->areasaturated=0 ; s->areazero=0 ; for (i=0 ; i<n ; i++) { if ( (list [i] ==-DBL_MAX) ) s->area_zero++ ; else if (list [i] ==DBL_MAX) s->areasaturated++ ; } else { sumintensity=sumintensity + (list [i]) ; sum2intensity=sum2intensity + (list [i]) * (list[i]) ; s [0]. area++ ; if (s->area>0) s [0]. average=sum_intensity/((double) s [0]. area) ;

s [0]. std_dev=sqrt (sum2_intensity/((double) s [0]. area)-s [0]. average*s [0]. average) ; s->median=s->average ; s [0]. area one sd=0 ; s [0]. area two sd=0 ; s [0]. average_one_sd=0. 0 ; s [0]. average two, sd=0. 0 ; s [0]. min=0. 0 ; s [0]. max=0. 0 ; else s [0]. area_one_sd=0 ; s [0]. area two sd=0 ; s [0]. average=0. 0 ; s [0]. std dev=0. 0 ; s [0]. median=0. 0 ; s [0]. average_one_sd=0. 0 ; s [0]. average_two_sd=0. 0 ; s [0]. min=0. 0 ; s [0]. max=0. 0 ; void linear regression (struct image data *composite, struct image_data *im_ref,

struct image data *im, int box) {int i, n, *p, sat=0 ; double xbar=0. 0, ybar=0. 0, <BR> xybar=0. 0,<BR> x2. bar=0. 0, y2bar=0. 0, sse=0.0, x, Y. temp ; n=composite [0]. boxes [box]. spot. area ; p=composite [0]. boxes [box]. spot. pixel positions ; im [0]. boxes [box]. R=0. 0 ; im [0]. boxes [box]. slope=0. 0 ; im [0]. boxes [box]. intercept=0. 0 ; if ( (p==NULL) || (n==0)) { if ( (p==NULL) && (n>0)) printf ("The pixel positions have not been gathered for linear regression... \n") ; else { for (i=0 ; i<n ; i++) {

x=imref [0]. data [p [i]] ; y=im [0]. data [p [i]] ; if ((x==MAX_INTENSITY) ## (y==MAX_INTENSITY)) sat++ ; else { xbar=xbar + x ; x2bar=x2bar + x*x ; ybar =ybar + y ; y2bar=y2bar + y*y ; xybar=xybar + x*y ; if ( (n-sat) >0) { xbar=xbar/ ( (double) (n-sat)) ; ybar=ybar/ ( (double) (n-sat)) ; x2bar=x2bar/ ( (double) (n-sat)) ; y2bar=y2bar/ ( (double) (n-sat)) ; xybar=xybar/ ( (double) (n-sat)) ; temp=x2bar-xbar*xbar ; if (temp ! =0. 0) {im [0]. boxes [box]. slope= (xybar-xbar*ybar)/temp ; im [0]. boxes [box]. intercept=ybar- im [0]. boxes [box]. slope*xbar ; else {im [0]. boxes [box]. slope=0. 0 ; im [0]. boxes [box]. intercept=0. 0 ;

for (i=0 ; i<n ; i++) {x=imref [0]. data [p [i]] ; y=im [0]. data [p [i]] ; if ( (x ! =MAX-INTENSITY) && (y ! =MAX_INTENSITY)) temp=y- (x*im [0]. boxes [box]. slope+im [0]. boxes [box]. inter cept) ; sse=sse+temp*temp ; temp=y2bar-ybar*ybar ; if (temp ! =0. 0) im [0]. boxes [box]. R=sqrt (1-see/(((double) (n-sat)) *temp)) ; else im [0]. boxes [box]. R=0. 0 ; } void lregression (double * x, double * y, int n, double * R, double * slope, double * intercept)

int i ; double xbar=0. 0, ybar=0. 0, x2bar=0. 0, y2bar=0. 0, temp, sse=0. 0, xybar=0. 0 ; *R = 0. 0 ; *slope = 0. 0 ; *intercept = 0. 0 ; if (n<2) return ; for (i=0 ; i<n ; i++) { xbar=xbar + x [i] ; x2bar=x2bar + x [i] *x [i] ; ybar =ybar + y [i] ; y2bar=y2bar + y [i] *y [i] ; xybar=xybar + x [i] *y [i] ; } xbar=xbar/ ( (double) n) ; ybar=ybar/ ( (double) n) ; x2bar=x2bar/ ( (double) n) ; y2bar=y2bar/ ( (double) n) ; xybar=xybar/ ( (double) n) ; temp=x2bar-xbar*xbar ; if (temp ! =0. 0) { *slope= (xybar-xbar*ybar)/temp ; *intercept=ybar- (*slope) *xbar ;

} for (i=0; i<n i++) temp=y [i]- (x [i] * (*slope) +*intercept) ; sse=sse+temp*temp ; } temp=y2bar-ybar*ybar ; if (temp ! =0. 0) *R=sqrt (1-see/(((double) n) *temp)) ; void pairwise_spot_statistics (struct image data *composite, struct image_data *im_ref, struct image-data *im, int box) int i, n, *p ; unsigned short int *listl, *list2 ; struct statistics * ref-spot, *spot, *ratio ; /*FILE * data-file ; */ double xbar=0. 0, ybar=0. 0, xybar=0. 0, x2bar=0. 0,

y2bar=0. 0,<BR> x,<BR> Y, sse=0. 0, temp ; double *log-ratio ; int area ; /*double * subx, * suby ; int isubs=20, nave, j, this-sub ; int *sorted *sorted2 ; */ ref_spot = &im->boxes [box]. reference->spot ; spot = &im->boxes [box]. wrtreference->spot ; ratio = &im->boxes [box]. wrtreference->ratio ; n=composite [0]. boxes [box]. spot. area ; p=composite [0]. boxes [box]. spot. pixel positions ; im [0]. boxes [box]. R=0. 0 ; im [0]. boxes [box]. slope=0. 0 ; im [0]. boxes [box]. intercept=0. 0 ; ref_spot->area=0 ; ref_spot->area one-sd=0 ; ref_spot->area_two_sd=0 ; ref_spot->area-zero=0 ; ref_spot->area_saturated=0 ; ref_spot->average=0. 0 ; refspot->stddev=0. 0 ; ref_spot->median=0. 0 ; ref_spot->average_one_sd=0. 0 ;

ref_spot->average_two_sd=0. 0 ; ref_spot->min=0. 0 ; refspot->max=0. 0 ; spot->area=0 ; spot->areaonesd=0 ; spot->areatwosd=0 ; spot->areazero=0 ; spot->areasaturated=0 ; spot->average=0. 0 ; spot->std_dev=0. 0 ; spot->median=0. 0 ; spot->average_one_sd=0. 0 ; spot->average_two_sd=0. 0 ; spot->min=0. 0 ; spot->max=0. 0 ; ratio->area=0 ; ratio->areaonesd=0 ; ratio->areatwosd=0 ; ratio->areazero=0 ; ratio->areasaturated=0 ; ratio->average=0. 0 ; ratio->stddev=0. 0 ; ratio->median=0. 0 ; ratio->averageonesd=0. 0 ; ratio->averagetwosd=0. 0 ; ratio->min=0. 0 ; ratio->max=0. 0 ;

if ( (n==0) | | (p==NULL)) { if ( (p==NULL) && (n>0) ) printf ("The pixel positions have not been gathered for pairwise spot satistics... \n") ; else { listl= (unsigned short int *) malloc (2*n*sizeof (unsigned short int)) ; if (listl==NULL) { printf ("failed malloc in pairwise spot statistic for listl\n") ; return ; list2=&listl [n] ; area=0 ; for (i=0 ; i<n ; i++) { x=imref [0]. data [p [i]] ; y=im [0]. data [p [i]] ; if ( (x ! =MAXINTENSITY) && (y ! =MAX_INTENSITY)) listl [area] = (unsigned short int) x ; list2 [area] = (unsigned short int) y ; xbar=xbar + x ; x2bar=x2bar + x*x ; ybar =ybar + y ; y2bar=y2bar + y*y ; xybar=xybar + x*y ; area++ ;

} if (area>0) { /*spot statistics*/ /*note, average is computed twice... but sort takes a long time, so no big deal*/ get-list-statistics (listl, area, ref-spot) ; get-list-statistics (list2, area, spot) ; /*ratio stuff*/ log_ratio= (double *) malloc (area*sizeof (double)) ; if (log_ratio==NULL) { printf ("failed malloc in pairwise spot statistics for log_ratio\n") ; return ; for (i=0 ; i<area ; i++) { if (list2 [i] ==0) log_ratio[i] =-DBL_MAX ; else if (listl [i] ==0) log-ratio [i] =DBLMAX ; else log_ratio [i] =log ( (double) (list2 [i])/ (double) (listl [i])) ; getdliststatistics (logratio, area, ratio) ; free (log-ratio) ;

/*sortedl= (int *) malloc (area*sizeof (int)) ; sorted2= (int *) malloc (area*sizeof (int)) ; for (i=0 ; i<area ; i++) { sortedl [i] =i ; sorted2 [i] =i ; qsortunsigned shortint (listl, sortedl, area) ; qsort unsigned short_int (list2, sorted2, area) ; */ /*subdivide for regression*/ /*subx= (double *) malloc (sizeof (double) *isubs) ; suby= (double *) malloc (sizeof (double) *isubs) ; nave= (int) ( (double) area/ (double) isubs +0. 5) ; if (nave==0) nave=l ; j=0 ; subx [0] =0. 0 ; suby [0]=0.0 ; this sub=0 ; for (i=0 ; ((i<area) && (this_sub<isubs));i++) { if (j<nave) { subx [thissub] +=listl [sortedl [i]] ; suby [this-sub] +=list2 [sorted2 [i]] ; j++ ; else { subx [this_sub]/= (double) j ; suby [this_sub]/= (double) j ; j=0 ;

this sub++ ; subx [this_sub]=0. 0 ; suby [this_sub]=0.0 ; } if (j>0) this_sub--; */ /*now the regression stuff*/ xbar=xbar/ ( (double) area) ; ybar=ybar/ ( (double) area) ; x2bar=x2bar/ ( (double) area) ; y2bar=y2bar/ ( (double) area) ; xybar=xybar/ ( (double) area) ; temp=x2bar-xbar*xbar ; if (temp ! =0. 0) { im [0]. boxes [box]. slope= (xybar-xbar*ybar)/temp ; im [0]. boxes [box]. intercept=ybar- im [0]. boxes [box]. slope*xbar ; else { im [0]. boxes [box]. slope=0. 0 ; im [0]. boxes [box]. intercept=0. 0 ; for (i=0 ; i<n ; i++) { x=imref [0]. data [p [i]] ; y=im [0]. data [p [i]] ;

if ( (x ! =MAX-INTENSITY) && (y!=MAX_INTENSITY)) temp=y- (x*im [0]. boxes [box]. slope+im [0]. boxes [box]. inter cept) ; sse=sse+temp*temp ; temp=y2bar-ybar*ybar ; if (temp ! =0. 0) im [0]. boxes [box]. R=sqrt (1-see/(((double) area) *temp)) ; else im [0]. boxes [box]. R=0. 0 ; /*data_file = fopen ("slope. txt","a") ; fprintf (data_file, "%i %f %f %f ", area, im [0]. boxes [box]. slope, im [0]. boxes [box]. intercep t, im [0]. boxes [box]. R) ; lregression (subx, suby, this-sub+1, &im [0]. boxes [box]. R, &im[0]. boxes [box]. slope, &im [0]. boxes [box]. intercept) ; fprintf (data_file, "%i of f %f\n", isubs, im [0]. boxes [box]. slope, im [0]. boxes [box]. int ercept,

im [0]. boxes [box]. R) ; fclose (data_file) ; free (subx) ; free (suby) ; free (sortedl) ; free (sorted2) ; */ /*only need one free, since only one malloc*/ free (listl) ; } string-stuff. c &num include"defs. h" char * get new file name (char * file_name, char * new path, char * ext) char * temp ; char * fname ; temp = change_path (file name, new path) ; &num ifdef WET DOT fname = change ext (temp, ext) ; #else fname = add-ext (temp, ext) ; #endif free (temp) ; return (fname) ;

char * add_ext (char * string, char * ext) char * fname ; fname = (char *) calloc ( (strlen (string) +strlen (ext) +l), sizeof (char)) ; if (fname==NULL) {printf ("Failed malloc in change_path... \n") ; exit (-l) ; } strcpy (fname, string) ; strcat (fname, ext) ; return (fname) ; char * change-path (char * filename char new-path) int i ; char * fname ; for (i= (strlen (file name)-1) ; (i> (-l)) && (file_name [i] !=SLASHCHAR) && (file_name [i] ! =':') ; i--) ; i++ ;

/*the 2 is for the SLASHCHAR and the termination character*/ fname= (char *) malloc (sizeof (char) * (2+strlen (new_path) + strlen (filename)-i)) ; if (fname==NULL) {printf ("Failed malloc in change_path... \n") ; exit (-l) ; } strcpy (fname, new_path) ; if (fname [strlen (fname)-l] ! =SLASHCHAR) strcat (fname, SLASHSTRING) ; strcat (fname, &filename [i]) ; return (fname) ; char * change-ext (char * string, char * ext) char * fname ; int i ; /*find the first. from the end of the string*/ for (i= (strlen (string)-1) ; (i> (-l)) && (string [i] ! ='.') ; i--) ; /*if no. then just add on the extension*/ if (i<0) i = strlen (string) ;

/*get the memory*/ /*fname = (char *) malloc ( (i + strlen (ext) +l) *sizeof (char)) ; */ fname = (char *) calloc (i + strlen (ext) +l, sizeof (char)) ; if (fname==NULL) {printf ("Failed malloc in change_path... \n") ; exit (-l) ; /*copy the part of the string without the extension*/ strncpy (fname, string, i) ; /*add on the extension*/ strncpy (&fname [i], ext, strlen (ext)) ; return (fname) ; /*counts the number of sub-string in string*/ int count-strstr (char * string, char * sub-string) char *location ; int number=0 ; location=strstr (string, sub-string) ; while ( (location ! =string) && (location ! =NULL)) number++ ; location=strstr (location+l, sub-string) ;

return (number) ; /*returns the location of the nth occurance of sub-string in string NULL if it fails*/ /*' !' !'does not allow overlap of sub-strings ! ! ! ! ! ! ! */ /*e. g. string ="and and and", sub string ="and and", will only find one (1) sub-string ! */ char * goto n strstr (char * string, int n, char * sub-string) char * location=NULL ; int number=0 ; int sub-length ; /*get the length of sub-string*/ sub_length=strlen (sub-string) ; /*don't do anything unless n>0, string *can* have the specified number of sub-strings and sub-string is at least one character in length*/ if ( (n>0) && (sub_length>0) && ((n*sub_length)<strlen(string)) ) { /*start at the beginning of the string*/ location=string ;

/*always look for one, keep looking until we've found them all or an error occurs (see man of strstr) */ do { location=strstr (location, sub-string) ; number++ ; /*if. we're not done and there's no error, start looking at the end of this occurance of sub string*/ if ( (location ! =NULL) && (number<n)) location+=sublength ; while ( (location ! =string) && (location ! =NULL) && (numbern)) /*should be the position of the nth occurance of sub-string or NULL if something went wrong*/ return (location) ;

structure. h /* printer structure */ typedef float Integrated ; struct overlap {int width, height ; char * image ; struct spot type-info {int number of types, * number ; char **type_name, * filename ; struct printer double spot-pitch, pin pitch row, pin pitch-column, spot_diameter,

pin_rattle, ax, bx, ay, by, cost, sint, cx, cy, dx, dy, *axp, *ayp, *bxp, *byp ; int spots per row, spots_per_column, <BR> <BR> <BR> <BR> <BR> pins per row,<BR> <BR> <BR> <BR> <BR> <BR> <BR> pins-per-column, origin_row, origin column, *row-offsets, *column_offsets, do coarse, do align, do-interpolate, subgridvectorization,

include missing, hexagonal, *spot type ; char **gene_id ; char *gene_id_column_headings ; struct spot_type_info spot_types ; struct statistics double average, std_dev, median, average one-sd, average_two_sd, min, max ; int area, <BR> <BR> <BR> <BR> area one sd,<BR> <BR> <BR> <BR> <BR> <BR> area two sd, area-zero, area saturated, * pixel positions ;

struct statistics flags int average, std_dev, median, average one-sd, average_two_sd ; int area, <BR> area one sd,<BR> area two sd, area-zero, area_saturated, min, max ; struct output data char * output path ; struct statistics-flags region, spot, background, <BR> ratio wrt reference,<BR> region wrt reference,<BR> spot wrt reference, background_wrt_reference,

region_reference, spot reference, background-reference, ratio-common, region_common, spot common, background-common ; int region-flag, <BR> <BR> <BR> <BR> <BR> region_common_flag,<BR> <BR> <BR> <BR> <BR> <BR> <BR> region wrt reference-flag,<BR> <BR> <BR> <BR> <BR> <BR> <BR> <BR> regionreferenceflag, spot_flag, spot-common-flag, spot wrt reference flag, spot_reference_flag, background-flag, background_common_flag, background_wrt_reference_flag, backgroundreferenceflag, ratio_common_flag, ratio_wrt_reference_flag ; int box_column, box-row, pin-row, pin-column, spot-row,

spot_column, spot_number, spot_perimeter, spot-width, spot height, spot type, numspots ; int spot xbar, spot_ybar, spotrbar, spot_rmin, spot_rmax, slope, intercept, R, <BR> spot-distance-from-grid,<BR> distance-from spot to, box, box_distance_from_grid, box dist to grid, spot_dist_to_grid, grid-row, grid-column, row-shift, col-shift ; int gene_id ;

} i struct multiimagestatistics struct statistics region, background, spot, ratio ; /* box structure */ struct box {struct statistics box, small box, spot, background ; /*this holds info about common unsaturated pixels with the reference image*/ struct multi-image_statistics *wrt reference ; /*this holds info about the common unsaturated pixels on the reference image*/ struct multi-image_statistics *reference ;

/*this holds the info about the common unsaturated with all images*/ struct multi-image-statistics *common ; int box_column, box row, pin row, pin_column, spot-row, spot_column, spot perimeter, spot-width, spot height, box-type, numspots ; double spot_xbar, spot_ybar, spot_rbar, spot_rmin, spot_rmax, spot distance-from grid, distance_from_spot_to_tox, box-distance-from-grid, row-shift, col-shift ; double-slope,

intercept, R ; unsigned short int threshold ; struct image_data { char * file name, * image description, * image-name ; int width, height, bits_per_pixel, white_is_zero, numboxes, numboxesfilledin ; _ unsigned short int * data ; Integrated * integrated_data, * integrated_data_small ; struct box * boxes ;

struct spot_finding_params {int crop width, crop height, furcation_type ; double fraction Ibar, estimated_spot_area ; struct find_boxes_params {int limit_furcation, limit_center, fast flag ; double fraction_by_furcation, center-tolerance ; struct spot_finding_params spot_params ; struct crop_image_data_params int shift-flag, shift-range-row, shift range column ; struct spot_finding_params spot_params ; struct output_image_params

char *output-path ; int tiff_zip_flag, tiff_jpg_flag, jpg_flag, ppm_flag, jpg_quality, integrated-flag, grid_flag, perimeter-flag, region-flag, background flag ; struct quality_params double intensity, background, roundness, area, distance_spot_to_box, distance_box_to_grid, distance_spot_to_grid ; struct integration_params { int mask_flag, mask file flag,

mask-width, square-flag, circle-flag, donut-flag, integration-width, integration_height, integration radius ;/*r int*/ double donut-width, donut_height, * mask, * perimeter_mask ; char * mask_file_name ; struct background_params int mask_flag, mask-file-flag, mask-width, square-flag, circle-flag, background-frame-width, background-width, background-height, background radius ;

double * mask ; struct mapspotsparams {int debug, do coarse, do-fine, docoarsepinbypin, do_fine_pin_by_pin, do_distance, increment_coarse, increment_fine, <BR> increment coarse pin by pin,<BR> incrementfinepinbypin, increment_distance, <BR> rangefinerow,<BR> range-fine column, range_coarse_pin_by_pin_row, range_coarse_pin_by_pin_column, range_coarse_pin_by_pin_row_autoselect, range_coarse_pin_by_pin_col_autoselect, range-fine pin by pin row, range_fine_pin_by_pin_column, range distance row, range_distance_column, snap negatives to-grid ;

struct find angles params {int do-find angles, iteration limit ; double x vector tolerance, y vector tolerance, convergence_distance ; /*structure containing parameters for the run*/ struct parameters {double genl_fermi_level ; struct printer printer-info ; struct findboxesparams findboxes ; struct crop_image_data_params crop_image_data ; struct output_image_params output_image ; struct quality params quality ; struct integration_params integration, integration-small ; struct inegration_params integration_out ; struct background_params background ; struct map_spots_params map_spots ; struct find angles, params find angles ; struct output_data output_flags ; struct map_image

{int *image, width, height, internal-width, internal_height, half-row, half_column, centerfirstspotrow, centerfirstspotcolumn, *row-offset, *col_offset, *number, *occupied ; double *occupied_distance, *intensity, *distance ; } i struct background-box int row, column, width, height ; sum-images. c #include"defs. h"

struct image data *sum images (struct image data *images [], int numimages, char *file_name_stub) int numsametype, i, j, l ; struct image_data *sum ; char *next ; double temp ; sum= (struct image-data *) malloc (sizeof (struct image_data)) ; sum->data=NULL ; sum->filename=NULL ; sum->imagename=NULL ; sum->imagedescription=NULL ; sum->boxes=NULL ; sum->integrated_data=NULL ; sum->width = images [0]->width ; sum->height = images [0]->height ; sum->bits_per_pixel=images [0] ->bits_per_pixel ; sum->white_is_zero=images [0]->whiteiszero ; num_same_type=1 ; for (i=l ; i<numimages ; i++) if ((sum->width==images [i] ->width) && (sum->height==images [i]->height) && (sum->bits_per_pixel==images [i] ->bits_per_pixel)) num_same_type++ ;

sum->data= (unsigned short int *) malloc (sum->width*sum->height*sizeof (unsigned short int)) ; if (sum->data==NULL) printf ("failed malloc in sum_images\n") ; exit (0) ; for (i=0 ; i< (sum->width*sum->height) ; i++) sum->data [i] =0 ; for (j=0 ; j< (sum->width*sum->height) ; j++) { temp=0. 0 ; for (i=0 ; i<num-images ; i++) if ((sum->width==images [i] ->width) && (sum->height==images [i]->height) && (sum->bitsperpixel==images [i]->bitsperpixel)) temp+= (double) images [i]->data [j] + (0.5/((double)num_same type)) ; } sum->data [j] = (unsigned short int) (temp/(double) num_same_type) ;

/* put an extension on the output filename */ 1=strlen (file_name_stub) ; fn_ext=(char*) malloc (sizeof (char) * (1+5)) ; if (fnext==NULL) { printf ("Failed malloc for filename in sum-images... \n") ; exit (0) ; strcpy (fnext, filenamestub) ; strcpy (&fnext [l],"sum") ; sum->filename=fnext ; return (sum) ; tiff. c #include"defs. h" &num define TIFF_ DEBUG 0 #define PPMDEBUG 0 struct image data *read-image (char *fname) {int len ;

len=strlen (fname) ; if (((fname [len-1] == 'M') # (fname [len-1] == 'm')) && ((fname [len-2] == 'P') # (fname [len-2] == 'p')) && ((fname [len-3] == 'P') # (fname [len-3] == 'p')) && (fname [len-4] =='.')) return (read ppm (fname)) ; else return (read_tiff (fname)) ; struct image_data *read_ppm (char *fname) struct image_data *our data=NULL ; char *s=NULL ; int max, i, n ; FILE *f=NULL ; our_data = (struct image data *) malloc (sizeof (struct image_data)) ; if (ourdata==NULL) {printf ("Failed malloc for image data in read_ppm...\n") ; exit (-l) ; ourdata->data=NULL ;

ourdata->boxes=NULL ; ourdata->integrateddata=NULL ; ourdata->filename=fname ; our_data->image_description= (char *) malloc (getpagesize () *sizeof (char)) ; ourdata->imagename = (char *) malloc (getpagesize () *sizeof (char)) ; f=fopen (fname,"rb") ; s= (char *) malloc (getpagesize () *sizeof (char)) ; if (f==NULL) {printf ("Failed to open %s... \n", fname) ; exit (-l) ; fscanf (f, "%S", s) ; if ((s [0] =='P') && (s [l] =='2')) {fgets (our_data [0] .image_description, getpagesize (), f) ; fgets (our_data [0] .image_description, getpagesize (), f) ; if (PPMDEBUG) printf ("%s\n", our_data [0] .image_description) ; fscanf (f, "%i %i %i", &ourdata [0]. width, &ourdata [0]. height, &max) ; if (PPMDEBUG)

printf ("#width=%i\n#height=%i\n#max=%i\n", ourdata [0]. width, ourdata [0]. height, max) ; n=ourdata [0]. height*ourdata [0]. width ; ourdata [0]. data= (unsigned short int *) malloc (n*sizeof (unsigned short int)) ; for (i=0 ; i<n ; i++) {fscanf (f,"ku", &max) ; ourdata [0]. data [i] =max ; } else printf ("%s is not a ppm file... \n", ourdata [0]. filename) ; fclose (f) ; exit (-l) ; fclose (f) ; return (ourdata) ; struct image_data *read tiff (char *fname) {struct image data *our data ; sizet freadcount=0 ;

unsigned long int ifdoffset=0, strip_offset=0, strip cnt=0, strip rows=0, strip_byte_cnt=0, doc name offset=0, <BR> <BR> <BR> <BR> docnamecnt=0,<BR> <BR> <BR> <BR> <BR> docdescoffset=0,<BR> <BR> <BR> <BR> docdesccnt=0,<BR> <BR> <BR> <BR> <BR> cnt=0, xres_offset=0, xres_num=0, xresden=0, yres_offset=0, yres_num=0, yres_den=0, planar_conf=1, res unit=0, samples_per_pixel=1, *dataoffsets=NULL, strip_len, Npixels, pixel_num, j ; unsigned char h [8], ifd [12], res [8],

*strip=NULL ; unsigned short int *data=NULL ; int i=0, <BR> ifdentries=0,<BR> tag=0, typ=0, <BR> compression=l,<BR> bps=l, photometric=0, endian=0 ;/* 0-little endian 1-big endian*/ FILE *f=NULL ; our_data= (struct image_data *) malloc (sizeof (struct image_data)) ; if (ourdata==NULL) {printf ("Failled malloc for image structure in read_tiff... \n") ; exit (-l) ; ourdata->data=NULL ; ourdata->boxes=NULL ; ourdata->integrateddata=NULL ;

ourdata->filename=fname ; our_data->image_description= (char *) malloc (getpagesize () *sizeof (char)) ; our data->imagename = (char *) malloc (getpagesize () *sizeof (char)) ; f=fopen (fname,"rb") ; if (f==NULL) {printf (."File os does not exist. \n", fname) ; exit (-l) ; fread-count=fread (h, 1, 8, f) ; if (fread_count !=8) {printf ("Error in read_tiff... (Perhaps this isn't really a tiff file)... \n") ; fclose (f) ; exit (-l) ; if ((h[0] = = 'I') && (h [l] =='I')) endian=0 ; else if ((h [0] =='M') && (h [l] =='M')) endian=l ; else

{printf ("Error in read_tiff... (Perhps this isn't really a tiff file)... \n") ; fclose (f) ; exit (-l) ; /* Start Little Endian */ if (endian==0) if ((h [2] =='*') && (h [3] == ( (unsigned char) 0))) ifd_offset = ((unsigned long int) h [4]) + ( (unsigned long int) h [5]) *256 + ( (unsigned long int) h [6]) *256*256 + ( (unsigned long int) h [7]) *256*256*256 ; fseek (f, ifdoffset, SEEKSET) ; freadcount=fread (h, 1, 2, f) ; ifd_entries= ((int) h [0]) + ( (int) h [l]) *256 ; if (TIFF_DEBUG) printf ("Number of ifd entries = %i\n", ifdentries) ; /* Read IFD Entries */ for (i=0 ; i<ifdentries ; i++) fread_count-fread (ifd, 1, 12, f) ;

tag= ( (int) ifd [0]) + ( (int) ifd [l]) *256 ; typ= ( (int) ifd [2]) + ( (int) ifd [3]) *256 ; cnt= ( (unsigned long int) ifd [4]) + ( (unsigned long int) ifd [5]) *256 + ( (unsigned long int) ifd [6]) *256*256 ; /* Image Width */ if (tag==256) {if (typ==3) ourdata [0]. width= ( (unsigned long int) ifd [8g) + ( (unsigned long int) ifd [9]) *256 ; else ourdata [0]. width= ( (unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 + ( (unsigned long int) ifd [101) *256*256 + ( (unsigned long int) ifd [ll]) *256*256*256 ; if (TIFF DEBUG) printf ("Image width = %i\n", ourdata [0]. width) ;

/* Image Height */ if (tag==257) if (typ==3) ourdata [0]. height= ( (unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 ; else ourdata [0]. height= ( (unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 + ( (unsigned long int) ifd [10]) *256*256 + ( (unsigned long int) ifd [ll]) *256*256*256 ; if (TIFF DEBUG) printf ("Image height = %i\n", ourdata [0]. height) ; /* Bits per Sample */ if (tag==258) if (typ==3) bps= ( (int) ifd [8]) + ((int) ifd [9]) *256 ;

ourdata [0]. bitsperpixel=bps ; if (TIFF_DEBUG) printf ("Bits per sample=i\n", bps) ; /* Compression */ if (tag==259) if (typ==3) compression= ( (int) ifd [8]) + ( (int) ifd [9]) *256 ; if (TIFF_DEBUG) if (compression==l) printf ("Compression=Uncompressed. \n") ; if (compression==2) printf ("Compression=CCITT 1D. \n") ; if (compression==3) printf ("Compression=Group 3 Fax. \n") ; if (compression==4) printf ("Compression=Group 4 Fax. \n") ; if (compression==5) printf ("Compression=LZW. \n") ; if (compression==6) printf ("Compression=PackBits. \n") ;

/* Photometric Interpretation */ if (tag==262) {if (typ==3) photometric= ( (int) ifd [8]) + ( (int) ifd [9]) *256 ; if (TIFF DEBUG) if (photometric==0) printf ("Photometric Interpretation=White is 0. \n") ; if (photometric==l) printf ("Photometric Interpretation=White is 1. \n") ; if (photometric==2) printf ("Photometric Interpretation=White is RGB. \n") ; if (photometric==3) printf ("Photometric Interpretation=White is RGB Pallete. \n") ; if (photometric==4) printf ("Photometric Interpretation=White is Tranparency Mask. \n") ; if (photometric==5) printf ("Photometric Interpretation=White is CMYK. \n") ; if (photometric==6)

printf ("Photometric Interpretation=White is YCbCr. \n") ; if (photometric==8) printf ("Photometric Interpretation=White is CIELab. \n") ; /* Document name */ if (tag==269) {if (typ==3) doc_name_offset = ((unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 ; else doc_name_offset = ((unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 + ( (unsigned long int) ifd [10]) *256*256 + ( (unsigned long int) ifd [ll]) *256*256*256 ; doc name_cnt= ( (unsigned long int) ifd [4]) + ((unsigned long int) ifd [5]) *256 +

( (unsigned long int) ifd [6]) *256*256 + ( (unsigned long int) ifd [7]) *256*256*256 ; /* Document description */ if (. tag==270) {if (typ==3) doc_desc_offset = ((unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 ; else docdescoffset= ( (unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 + ( (unsigned long int) ifd [10]) *256*256 + ( (unsigned long int) ifd [ll]) *256*256*256 ; doc_desc-cnt = ((unsigned long int) ifd [4]) + ( (unsigned long int) ifd [5]) *256 + ( (unsigned long int) ifd [6]) *256*256 +

( (unsigned long int) ifd [7]) *256*256*256 ; } /* Strip offset offsets */ if (tag==273) {if (typ==3) @ strip_offset = ((unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 ; else strip_offset = ((unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 + ( (unsigned long int) ifd [10]) *256*256 + ( (unsigned long int) ifd [ll]) *256*256*256 ; strip cnt= ( (unsigned long int) ifd [4]) + ( (unsigned long int) ifd [5]) *256 + ( (unsigned long int) ifd [6]) *256*256 + ( (unsigned long int) ifd [7]) *256*256*256 ; if (TIFF DEBUG)

printf ("Number of strips = %lu\n", strip_cnt) ; /* Strip rows */ if (tag==278) {if (typ==3) strip_rows = ((unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 ; else strip_rows = ((unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 + ( (unsigned long int) ifd [10]) *256*256 + ( (unsigned long int) ifd [ll]) *256*256*256 ; if (TIFF DEBUG) printf ("Rows per strip = %lu\n", strip_rows) ; /* Total byte count for image, Strip Byte Count */ if (tag==279) {if (typ==3)

strip_byte_cnt = ((unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 ; else strip_byte_cnt = ((unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 + ( (unsigned long int) ifd [10]) *256*256 + ( (unsigned long int) ifd [ll]) *256*256*256 ; if (TIFF DEBUG) printf ("Total bytes in image = %lu\n", stripbytecnt) ; /* X-resolution offset */ if (tag==282) {if (typ==5) xres_offset = ((unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 + ( (unsigned long int) ifd [10]) *256*256 +

( (unsigned long int) ifd [ll]) *256*256*256 ; /* Y-resolution offset */ if (tag==283) if (typ==5) @ yres_offset = ((unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 + ( (unsigned long int) ifd [10]) *256*256 + ((unsigned long int) ifd [ll]) *256*256*256 ; /* Planar configuration */ if (tag==284) {if (typ==3) planar-conf= ( (unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 ; if (TIFF_DEBUG) if (planar conf==l) printf ("Planar Configuration=Chunky. \n") ;

if (planarconf==2) printf ("Planar Configuration=Planar. \n") ; } /* Resolution unit */ if (tag==296) {if (typ==3) res_unit = ((unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 ; if (TIFF DEBUG) if (res unit==1) printf ("Resolution Unit=Not Specified. \n") ; if (res unit==2) printf ("Resolution Unit=Inch. \n") ; if (res unit==3) printf ("Resolution Unit=Centimeter. \n") ; } } /* Samples per pixel */ if (tag==339) {if (typ==3)

samples_per_pixel= ( (unsigned long int) ifd [8]) + ( (unsigned long int) ifd [9]) *256 ; if (TIFF_DEBUG) printf ("Samples per pixel = %lu\n", samples_per_pixel) ; /* Read Document Name */ if (doc_name_offset ! = 0) {ourdata [0]. imagename= (char *) malloc (sizeof (char) * (doc_name_cnt+1)) ; fseek (f, doc_name_offset, SEEK_SET) ; freadcount=fread (ourdata [0]. imagename, 1, docnamecnt, f) ; ourdata [0]. imagename [docnamecnt] =0 ; if (TIFF_DEBUG) printf ("Document name = %s\n", ourdata [0]. imagename) ; /* Read Document Description */ if (doc descoffset ! =0)

{ourdata [0]. imagedescription= (char *) malloc (sizeof (char) * (docdesccnt+l)) ; fseek (f, docdescoffset, SEEKSET) ; freadcount=fread (ourdata [0]. imagedescription, 1, docdesccnt, f) ; our_data[0].image_description [doc_desc_cnt] = 0 ; if (TIFF_DEBUG) printf ("Document description = %s\n", ourdata [0]. imagedescription) ; /* Read X and Y Resolutions */ if (xresoffset ! =0) {fseek (f, xres_offset, SEEK_SET) ; freadcount=fread (res, 1, 8, f) ; xres_num = ((unsigned long int) res [0]) + ( (unsigned long int) res [l]) *256 + ( (unsigned long int) res [2]) *256*256 + ( (unsigned long int) res [3]) *256*256*256 ; xres_den = ((unsigned long int) res [4]) + ( (unsigned long int) res [5]) *256 + ( (unsigned long int) res [6]) *256*256 + ( (unsigned long int) res [7]) *256*256*256 ;

if (yres_offset ! = 0) {fseek (f, yres_offset, SEEK_SET) ; freadcount=fread (res, 1, 8, f) ; yres_num = ((unsigned long int) res [0]) + ( (unsigned long int) res [l]) *256 + ( (unsigned long int) res [2].) *256*256 + ( (unsigned long int) res [3]) *256*256*256 ; yres_den = ((unsigned long int) res [4]) + ( (unsigned long int) res [5]) *256 + ( (unsigned long int) res [6]) *256*256 + ( (unsigned long int) res [7]) *256*256*256 ; } /* Read Strip Offsets */ data offsets= (unsigned long int *) malloc (sizeof (unsigned long int) * strip_cnt) ; if (stripcnt>l) {fseek (f, stripoffset, SEEKSET) ; for (cnt=0 ; cnt<stripcnt ; cnt++) fread_count = fread (res, 1, 4, f) ; data_offsets [cnt] = ((unsigned long int) res [0]) + ( (unsigned long int) res [l]) *256 +

( (unsigned long int) res [2]) *256*256 + ( (unsigned long int) res [3]) *256*256*256 ; else data_offsets[0] = strip_offset ; /* Get the Image Data */ Npixels=ourdata [0]. width*ourdata [0]. height ; data= (unsigned short int *) malloc (samples_per_pixel*Npixels*sizeof (unsigned short int)) ; striplen=striprows*ourdata [0]. width*bps/8 ; if (TIFF DEBUG) printf ("Strip length = %lu\n", strip_len) ; strip= (unsigned char *) malloc (sizeof (unsigned char) *strip_len) ; for (cnt=0 ; cnt<strip_cnt ; cnt++) {fseek (f, data offsets [cnt], SEEK_SET) ; freadcount=fread (strip, 1, strip_len, f) ; if (bps==16) pixel_num=cnt*strip_len/2 ; for (j=0 ; j<strip_len ; j=j+2)

if ((pixel_num+j/2) <Npixels) data [pixel_num+j/2] = ((unsigned short int) strip [j]) + ( (unsigned short int) strip [j+1] *256) ; if (bps==8) {pixelnum=cnt*striplen ; for (j=0 ; j<strip_len ; j++) if ((pixel_num+j) <Npixels) data [pixelnum+j] = ( (unsigned short int) strip [j] *256) ; } else {fclose (f) ; exit (-l) ; /* Start Big Endian */ fclose (f) ; free (dataoffsets) ; dataoffsets=NULL ;

free (strip) ; strip=NULL ; ourdata [0]. data=data ; return (our-data) write jpeg. c &num include"defs. h" void write_jpeg (struct image data * image, int quality, char *output path) /* This struct contains the JPEG compression parameters and pointers to * working space (which is allocated as needed by the JPEG library).

* It is possible to have several such structures, representing multiple * compression/decompression processes, in existence at once. We refer * to any one struct (and its associated working data) as a"JPEG object".

*/ struct jpeg_compress_struct cinfo ; /* This struct represents a JPEG error handler. It is declared separately * because applications often want to supply a specialized error handler * (see the second half of this file for an example).

But here we just * take the easy way out and use the standard error handler, which will * print a message on stderr and call exit () if compression fails.

* Note that this struct must live as long as the main JPEG parameter * struct, to avoid dangling-pointer problems.

*/ struct jpegerrormgr jerr ; /* More stuff */ FILE * outfile ;/* target file */ JSAMPROW row_pointer [l] ;/* pointer to JSAMPLE row [s] */ int row-stride ;/* physical row width in image buffer */ JSAMPLE * image-buffer ; unsigned char * data_8bit ; int 1 ; int width, height ;

char * fname ; unsigned short int * data ; char * ext=". jpg" ; width=image->width ; height=image->height ; data=image->data ; fname=image->filename ; /* change the path and put an extension on the output filename */ fname = get_new_file_name (image [0]. filename, outputpath, ext) ; printf ("%s\n", fname) ; data-8bit= (unsigned char *) malloc (sizeof (unsigned char) *width*height) ; if (data8bit==NULL) {printf ("Failed to allocate memory for write_jpeg... \n") ; exit (0) ; for (1=0 ; 1< (width*height) ; 1++) data8bit [l] = (unsigned char) (256-data [l]/256) ; image-buffer = (JSAMPLE *) data_8bit ;

/* Step 1 : allocate and initialize JPEG compression object */ /* We have to set up the error handler first, in case the initialization * step fails. (Unlikely, but it could happen if you are out of memory.) * This routine fills in the contents of struct jerr, and returns jerr's * address which we place into the link field in cinfo.

*/ cinfo. err = jpegstderror (&jerr) ; /* Now we can initialize the JPEG compression object.

*/ jpegcreatecompress (&cinfo) ; /* Step 2 : specify data destination (eg, a file) */ /* Note : steps 2 and 3 can be done in either order.

*/ /* Here we use the library-supplied code to send compressed data to a * stdio stream. You can also write your own code to do something else.

* VERY IMPORTANT : use"b"option to fopen () if you are on a machine that

* requires it in order to write binary files.

*/ if ( (outfile = fopen (fname,"wb")) == NULL) {printf ("Faild to open file s in write-jpeg... \n", fname) ; return ; jpegstdiodest (&cinfo, outfile) ; /* Step 3 : set parameters for compression */ /* First we supply a description of the input image.

* Four fields of the cinfo struct must be filled in : */ cinfo. image width = width ;/* image width and height, in pixels */ cinfo. image_height = height ; cinfo. input_components = 1 ;/* # of color components per pixel */ cinfo. in color-space = JCSGRAYSCALE ;/* colorspace of input image */ /* Now use the library's routine to set default compression parameters.

* (You must set at least cinfo. in color-space before calling this, * since the defaults depend on the source color space.) */

jpegsetdefaults (&cinfo) ; /* Now you can set any non-default parameters you wish to.

* Here we just illustrate the use of quality (quantization table) scaling : */ jpegsetquality (&cinfo, quality, TRUE/* limit to baseline-JPEG values */) ; /* Step 4 : Start compressor */ /* TRUE ensures that we will write a complete interchange-JPEG file.

* Pass TRUE unless you are very sure of what you're doing.

*/ jpegstartcompress (&cinfo, TRUE) ; /* Step 5 : while (scan lines remain to be written) */ /* jpegwritescanlines (...) ; */ /* Here we use the library's state variable cinfo. next-scanline as the * loop counter, so that we don't have to keep track ourselves.

* To keep things simple, we pass one scanline per call ; you can pass * more if you wish, though.

*/ row_stride = width ;/* JSAMPLEs per row in image-buffer while (cinfo. next_scanline < cinfo. image height) /* jpegwritescanlines expects an array of pointers to scanlines.

* Here the array is only one element long, but you could pass.

* more than one scanline at a time if that's more convenient.

*/ row_pointer [0] = & imagebuffer [cinfo. next_scanline * rowstride] ; (void) jpeg_write_scanlines (&cinfo, row_pointer, 1) ; /* Step 6 : Finish compression */ jpegfinishcompress (&cinfo) ; /* After finish-compress, we can close the output file. */ fclose (outfile) ; /* Step 7 : release JPEG compression object */

/* This is an important step since it will release a good deal of memory. */ jpegdestroycompress (&cinfo) ; /* And we're done ! */ free (fname) ; } write tiff. c #include"defs. h" void writetiffjpeg (struct image data * image, int quality, char *output path) { TIFF* out ; uint32 w, h ; uint32 row, col ; unsigned char * buf ; char *fname ; unsigned short int * data ; w=image->width ; h=image->height ; data=image->data ;

fname=image->filename ; /* change the output file and put the extension on the output filename */ fname = get_new_file_name (image [0]. file name, output_path,"-jpg. tif") ; printf ("%s\n", fname) ; /* open the file */ out = TIFFOpen (fname,"w") ; if (out==NULL) {printf ("Failed to open file As in writetiffjpeg... \n", fname) ; return ; /* set the tags */ TIFFSetField (out, TIFFTAGCOMPRESSION, COMPRESSION_JPEG) ; TIFFSetField (out, TIFFTAGJPEGQUALITY, quality) ; TIFFSetField (out, TIFFTAGJPEGCOLORMODE, JPEGCOLORMODERAW) ; /*TIFFSetField (out, TIFFTAGCOMPRESSION, COMPRESSION_DEFLATE) ; */ TIFFSetField (out, TIFFTAGIMAGEWIDTH, w) ; TIFFSetField (out, TIFFTAGIMAGELENGTH, h) ;

TIFFSetField (out, TIFFTAGBITSPERSAMPLE, 8) ; TIFFSetField (out, TIFFTAGPLANARCONFIG, PLANARCONFIGCONTIG) ; TIFFSetField (out, TIFFTAGSAMPLESPERPIXEL, 1) ; TIFFSetField (out, TIFFTAGPHOTOMETRIC, PHOTOMETRICMINISWHITE) ; TIFFSetField (out, TIFFTAGROWSPERSTRIP, 8) ; /* get memory */ buf = TIFFmalloc (w) ; for (row = 0 ; row < h ; row++) { /* convert to 8 bits */ for (col=0 ; col<w ; col++) buf [col] = (unsigned char) (data [row*w+col]/256) ; /* write this row */ if (TIFFWriteScanline (out, buf, row, 0) < 0) break ; (void) TIFFClose (out) ; free (fname) ; void write_tiff_zip (struct image-data * image, char *output_path) TIFF* out ; uint32 w, h ;

uint32 row, col ; unsigned char * buf ; char *fname ; unsigned short int * data ; w=image->width ; h=image->height ; data=image->data ; fname=image->filename ; /* change the path and add the extension on the output filename */ fname = get new-file name (image [0]. filename, outputpath,"-zip. tif") ; printf ("os\n", fname) ; /* open the file */ out = TIFFOpen (fname,"w") ; if (out==NULL) {printf ("Failed to open file %s in write_tiff_zip... \n", fname) ; return ; /* set the tags */

TIFFSetField (out, TIFFTAGCOMPRESSION, COMPRESSION DEFLATE) ; TIFFSetField (out, TIFFTAGIMAGEWIDTH, w) ; TIFFSetField (out, TIFFTAGIMAGELENGTH, h) ; TIFFSetField (out, TIFFTAGBITSPERSAMPLE, 8) ; TIFFSetField (out, TIFFTAGPLANARCONFIG, PLANARGONFIGCONTIG) ; TIFFSetField (out, TIFFTAGSAMPLESPERPIXEL, 1) ; TIFFSetField (out, TIFFTAGPHOTOMETRIC, PHOTOMETRICMINISWHITE) ; TIFFSetField (out, TIFFTAGROWSPERSTRIP, 1) ; /* get memory */ buf = TIFFmalloc (w) ; for (row = 0 ; row < h ; row++) { /* convert to 8 bits */ for (col=0 ; col<w ; col++) buf [col] = (unsigned char) (data [row*w+col]/256) ; /* write this row */ if (TIFFWriteScanline (out, buf, row, 0) < 0) break ; (void) TIFFClose (out) ; free (fname) ; } wspots. c

#include "defs. h" int main (int argc, char *argv []) struct parameters all_params ; struct image_data **images=NULL ; struct image_data *sum=NULL ; struct overlap oimage ; int num-images, image, box ; char *input_filename=NULL, &*printer_filename=NULL ; oimage. image=NULL ; oimage. width=0 ; oimage. height=0 ; credits () ; check_command_line (argc, argv) ;

nus-images = argc-2 ; printer filename=argv [l] ; if (num images==l) /* first read in the parameters and image */ all_params.output_flags.ratio_common_flag=0 ; setparameterdefaults (printerfilename, &allparams) ; /* it makes no sense to output the ratio stuff or common unsaturated statistics for one image*/ all_params.output_flags.ratio_common_flag=0 ; all_params. output_flags. slope=0 ; all_params.output_flags.intercept=0 ; all_params.output_flags.R=0 ; all_params.output_flags.background_common_flag=0 ; allparams. outputflags. regioncommonflag=0 ; all_params. output-flags. spot common-flag=0 ; input_filename-argv[2] ; sum = read_image (input_filename) ; find array (sum, &all_params) ; createoverlapimage (&oimage,

&all_params. crop_image_data.spot_params, &allparams. background, &all_params.integration_out, &allparams. printerinfo) ; for (box=0 ; box<sum [0]. numboxes ; box++) {sum [0]. boxes [box]. slope=0 ; sum [0]. boxes [box]. intercept=0 ; sum [0]. boxes [box]. R=0 ; compute-local background (sum, &all_params. background, &sum [0]. boxes [box], &oimage, &sum [0]. boxes [box]. background) ; } integrate_boxes (sum, &allparams. integrationout) ; write data (0, 1, &sum, &all_params.printer_info &all_params.output-flags, all_params.output_flags.output_path) ; draw info (sum, &allparams, &oimage) ; free_image (sum) ; else

images= (struct image-data malloc ((num_images) *sizeof (struct image_data *)) ; if (images==NULL) {printf ("could not allocate memory for image pointers ! \n") ; exit (-l) ; for (image=0 ; image<numimages ; image++) input_filename=argv [2+image] ; if (image==0) printf ("Reading image number'ii (reference) ----%s\n", (int) 1+image, input_filename) ; else printf ("Reading image number (int) 1+image, input_filename) ; images [image] = read_image (input_filename) ; /*this sets default parameters and also sets user defined parameters*/ setparameterdefaults (printerfilename, &allparams) ; /*But, if there are only two images the common stuff is redundant so don't do it*/

/*Note : Don't change this unless you also allocate memory for these statistics in multi_image_create_boxes or bad things might happen in write_data*/ if (numimages==2) { all_params. output_flags.ratio_common_flag=0 ; all_params. output-flags. background common flag=0 ; all_params. outputflags. regioncommonflag=0 ; all_iparams. output_flags.spot_common_flag=0 ; if ( (same-size (images, num images) ==l) && (all_params. printer-info. do align==0)) { sum = sum-images (images, numimages, "composite image") ; find array multi (sum, images, num_images, &allparams) ; else { if (all_params. printer_info. do_align==0) printf ("Images were not the same size, aligning... \n") ; else printf ("Alignment forced... \n") ; align-images (images, numimages, &allparams) ; for (image=l ; image<numimages ; image++) free (images [image3->boxes) ;

sum=sumimages (images, numimages, "composite_image") ; sum->boxes=images [0]->boxes ; sum->numboxes=images [0]->numboxes ; sum->integrateddata=NULL ; printf ("integrating sum data\n") ; integrate_boxes (sum, &all_params. integration) ; crop_image_data (sum, &all_params. crop_image_data.spot_params) ; printf ("creating new boxes\n") ; multi image create boxes (sum, images, num_images, &all_params.integration_out, &allparams. integrationsmall, &all_params. background) ; printf ("cropping data\n") ; if (all_params.crop_image_data.shift_flag = = 0) multi_image_crop_image_data (sum, images, numimages, &all_params.crop_image_data.spot_params) ; else multiimagecropimagedatashift (sum, images, num_images,

&all_params. crop-image data) ; } /* Build overlap/pixel attribute image*/ /* Overlap means that a given pixel might be both a background pixel and a spot pixel */ printf ("creating overlap image\n") ; createoverlapimage (&oimage, sum, &allparams. cropimagedata. spotparams, &all params. background, &allparams. integrationout, &allparams. printerinfo) ; /*get the local background*/ printf ("local background\n") ; for (image=0 ; image<num-images ; image++) { for (box=0 ; box<sum [0]. numboxes ; box++) { compute_local_background (images [image], &all_params. background, &images [image] [0]. boxes [box], &oimage, &images [image] [0]. boxes [box]. background) ;

/*get the pairwise common unsaturated background and region data*/ printf ("pairwise common unsaturated background and region data\n") ; for (image=l ; image<numimages ; image++) { add saturation to overlap (&oimage, _ images [image]) ; add_saturation_to_overlap (&oimage, images [0]) ; for (box=0 ; box<sum [0]. numboxes ; box++) { computelocalbackgroundcommon (images [image], &allparams. background, &images [image] [0]. boxes [box], &oimage, &images [image] [0]. boxes [box]. w rtreference->background) ; compute-local background common (images [0], &all_params. background, &images [image] [0]. boxes [box], &oimage, &images [image] [0]. boxes [box]. reference->background) ; integrate region common (images [image], &allparams. integrationout, images [image] [0]. boxes [box]. box-row,

images [image] [0]. boxes [box]. box column, &images [image] [0]. boxes [box]. wrtreference->region, &oimage) ; integrate region common (images [image], &allparams. integrationout, images [image] [0]. boxes [box]. box-row, images [image] [0]. boxes [box]. box column, &images [image] [0]. boxes [box]. reference->region, &oimage) ; remove-attributes (&oimage, SATURATED PIXEL) ; /* Get the positions of the pixels in each spot in the composite image, and perform linear regression using the first image as the reference */ printf ("pairwise common unsaturated spot and ratio stats\n") ; /*collect the common unsaturated (between image and reference only) stats*/ for (box=0 ; box<sum [0]. numboxes ; box++) {

get_largest_spot_pixels (sum, &sum [0]. boxes [box], &all_params.crop_image_data.spot_params) ; images [0] [0]. boxes [box]. slope=1. 0 ; images [0] [0]. boxes [box]. intercept=0. 0 ; images [0] [0]. boxes [box]. R=1. 0 ; for (image=l ; image<numimages ; image++) { pairwise spot-statistics (sum, images [0], images [image], box) ; /*if we have more than two images, do the common unsaturated calculations*/ /*Note : Don't change this unless you also allocate memory for these statistics in multiimagecreateboxes or bad things might happen in write data*/ if (num_images>2) printf ("common unsaturated stats\n") ; for (image=0 ; image<numimages ; image++) add-saturation to overlap (&oimage, images [image]) ; _ for (image=0 ; image<num-images ; image++) for (box=0 ; box<sum [0]. numboxes ; box++) { computelocalbackgroundcommon (images [image], &all_params. background,

&images [image] [0]. bpxes [box], &oimage, &images [image] [0]. boxes [box]. common->background) ; integrate region common (images [image], &allparams. integrationut, images [image] [0]. boxes [box]. box-row, images [image] [0]. boxes [box]. box column, &images [image] [0]. boxes [box]. common->region, &oimage) ; spotstatisticscommon (images [image],<BR> images [0], sum [0]. boxes [box]. spot. pixel_positions, sum [0]. boxes [box]. spot. area, &oimage, &images [image] [0]. boxes [box]. common->spot, &images [image] [0]. boxes [box]. common->ratio) ; } /* output the images */ for (image=0 ; image<numimages ; image++)

draw-info (images [image], &all_params, &oimage) ; /* Write out the images and data */ for (image=0 ; image<numimages ; image++) write-data (image, num images, images, &all_params. printer-info, &all_params.output_flags, allparams. outputflags. outputpath) ; for (box=0 ; box<sum [0]. numboxes ; box++) if (sum [0]. boxes [box]. spot. pixel positions ! =NULL) free (sum [0]. boxes [box]. spot. pixel_positions) ; free-image (sum) ; /* Free memory */ for (image=0 ; image<numimages ; image++) fret-image (images [image]) ; free (images) ; free (oimage. image) ; /***** Many other hunks of memory are not let go--- see structure. h ******/ return (0) ;