View Javadoc

1   /*** DataSetColorModel.java - part of the MirkE (say murky) application for colormetric analysis emphesizing
2   kinetics.
3   
4   Created by: Scott Menor on 21 July, 2004.
5   
6   Copyright (c) 2004 Arizona State University - Cancer Research Institute. All rights reserved.
7   
8   MirkE is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12  
13  MirkE is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU General Public License for more details.
17  
18  You should have received a copy of the GNU General Public License
19  along with MirkE; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  US
21  */
22  
23  package edu.asu.cri.MirkE.gui;
24  
25  import java.util.*;
26  import java.awt.*;
27  import java.awt.color.*;
28  import edu.asu.cri.MirkE.exceptions.MirkEApplicationException;
29  import edu.asu.cri.MirkE.exceptions.MirkEFileNotFoundException;
30  import edu.asu.cri.MirkE.exceptions.MirkESystemException;
31  import java.io.*;
32  import java.beans.*;
33  import org.apache.commons.logging.Log;
34  import org.apache.commons.logging.LogFactory;
35  
36  import edu.asu.cri.MirkE.*;
37  
38  /***
39  
40  @author Scott Menor
41  @version 0.3.0, 2 februrary, 2004
42  */
43  
44  public class DataSetColorModel {
45  	static Map wavelengthToCIE_XYZ = null;
46  	static ICC_ColorSpace rgbSpace;
47  
48  	 /***
49       * Logger
50       * */
51      private static final Log log = LogFactory.getLog(DataSetColorModel.class);
52  
53  	/***
54  		@param mirke
55  	 @param query HQL query
56  
57  	 @return color
58  	 */
59  	public static java.awt.Color toColor(MirkE mirke,
60  								String query) {
61  		// TODO - implement
62  		return null;
63  	}
64  
65  	/***
66  	 * @param mirke
67  	 * @param observableToMinValueMap
68  	 * @param observableToMeanValueMap
69  	 * @param observableToMaxValueMap
70  	 * @return color
71  	 * @throws MirkEApplicationException
72  	 */
73  	public static java.awt.Color toColor(MirkE mirke,
74  								Map observableToMinValueMap,
75  								Map observableToMeanValueMap,
76  								Map observableToMaxValueMap) throws MirkESystemException {
77  
78  		// TODO - pick a color based on the representation and linear/log scale (for now, ignoring them)
79  
80  		// TODO - properly add/subtract emission/absorbsion in XYZ space for each observation
81  
82  		Color color = Color.white;
83  
84  		Set observableToMeanValueMapSet = observableToMeanValueMap.entrySet();
85  		Iterator observableToMeanValueSetIterator = observableToMeanValueMapSet.iterator();
86  		while (observableToMeanValueSetIterator.hasNext()) {
87  			Map.Entry observableToMeanValueEntry = (Map.Entry)observableToMeanValueSetIterator.next();
88  
89  			String observableName = observableToMeanValueEntry.getKey().toString();
90  
91  			//String observableType = observableName.substring(0, 1);
92  			String wavelengthString = observableName.substring(2, observableName.indexOf("nm"));
93  
94  			Integer wavelength = new Integer(wavelengthString);
95  
96  			double minValue  = ((Double)observableToMinValueMap.get(observableName)).doubleValue();
97  			double meanValue = ((Double)observableToMeanValueEntry.getValue()).doubleValue();
98  			double maxValue  = ((Double)observableToMaxValueMap.get(observableName)).doubleValue();
99  
100 			// TODO - get a wavelength number from the observable 
101 			//(would be nice to use a Unit class that stores units and measured values separately rather than String 
102 			//(just worried about doubling the number of database accesses))
103 
104 			if (maxValue - minValue != 0) {
105 				try {
106 				color = wavelengthToColor(wavelength,
107 										  (meanValue-minValue)/(maxValue - minValue));
108 				} catch(MirkEFileNotFoundException nf){
109 				    
110 				   throw new MirkESystemException(true);
111 				    
112 				    	
113 				}catch(MirkEApplicationException ex){
114 				    
115 				    throw new MirkESystemException(true);
116 				
117 			}
118 			}
119 		}
120 		return color;
121 	}
122 
123 	/***
124 
125 	 @return wavelengthToCIE_XYZ <code>Map</code> from wavelength in nm to a <code>Vector</code> containing components of a corresponding CIE_XYZ color
126 	 */
127 
128 public static Map getWavelengthToCIE_XYZ() throws  MirkEFileNotFoundException {
129     	XMLDecoder decoder = null;
130        	// this will allow the executable jar to run
131     
132    // 	File file = new File("//mirke//configuration","wavelengthToCIE_XYZ.xml");
133     	File file = new File("configuration", "wavelengthToCIE_XYZ.xml");
134 		if (wavelengthToCIE_XYZ == null) {
135 			try{
136 			   	decoder = new XMLDecoder(new FileInputStream(file)); // TODO - remove hard-coded filename
137 			}catch (FileNotFoundException fn){
138 
139 			    throw new MirkEFileNotFoundException((Throwable)fn);
140 			}catch(IOException io){
141 			    
142 			    io.printStackTrace();
143 			}
144 				
145 				wavelengthToCIE_XYZ = (HashMap)decoder.readObject();
146 				decoder.close();
147 				// couldn't read wavelengthToCIE_XYZ from the source file; 
148 				//TODO - recover gracefully, if possible p				System.err.println(e);
149 		}
150 
151 		return wavelengthToCIE_XYZ;
152 	}
153 
154 	/*** Default constructor
155 		*/
156 	public DataSetColorModel() {}
157 	/***
158 	 * @param wavelength
159 	 * @return CIE XYZ components corresponding to a specific <code>wavelength<code> of monochromatic light at a standard intensity
160      */
161 	public static float[] wavelengthToCIE_XYZcomponents(Integer wavelength) throws MirkEApplicationException,  MirkEFileNotFoundException {
162 
163 
164 		Vector CIE_XYZcomponentsFromWavelength = (Vector)getWavelengthToCIE_XYZ().get(wavelength);
165 
166 		float[] CIE_XYZcomponents = new float[CIE_XYZcomponentsFromWavelength.size()];
167 		for (int i=0;i<CIE_XYZcomponentsFromWavelength.size();i++) {
168 			CIE_XYZcomponents[i] = ((Float)CIE_XYZcomponentsFromWavelength.elementAt(i)).floatValue();
169 		}
170 
171 		return CIE_XYZcomponents;
172 	}
173 
174 	/*** Convert from a wavelength of monochromatic light to an approximate Color
175 
176 		@param wavelength an <code>double</code> wavelength (in nm)
177 		@param alpha The alpha channel component of the returned <code>Color</code>
178 
179 		@return color
180 	 * @throws MirkEApplicationException
181 		*/
182  	public static Color wavelengthToColor(double wavelength,
183 										  double alpha) throws MirkEApplicationException ,MirkEFileNotFoundException{
184  		return wavelengthToColor(new Integer((int)Math.round(wavelength)),
185  								 (float)alpha);
186 	}
187 
188 	/*** Convert from a wavelength of monochromatic light to an approximate Color
189 
190 		@param wavelength an <code>Integer</code> wavelength (in nm)
191 		@param alpha The alpha channel component of the returned <code>Color</code>
192 
193 		@return color
194 	 * @throws MirkEApplicationException
195 		*/
196 	public static Color wavelengthToColor(Integer wavelength,
197 										  double alpha) throws MirkEApplicationException, MirkEFileNotFoundException {
198 		return wavelengthToColor(wavelength,
199 								 (float)alpha);
200 	}
201 
202 	/*** Convert from XYZ values to a Color
203 
204 		@param xyzValues
205 
206 		@return color
207 	 * @throws MirkEApplicationException
208 		*/
209 	public static Color xyzToColor(float[] xyzValues) throws MirkEApplicationException{
210 		return xyzToColor(xyzValues, 1.0f);
211 	}
212 
213 	/*** Convert from XYZ values to a Color
214 	 *
215 	 *@param xyzValues
216 	 * @param alpha
217 	 *
218 	 * @return color
219 	 * @throws MirkEApplicationException
220 	 */
221 	public static Color xyzToColor(float[] xyzValues,
222 								   float alpha) throws MirkEApplicationException{
223 
224 		if (rgbSpace == null) {
225 			rgbSpace = new ICC_ColorSpace(ICC_Profile.getInstance(ICC_ColorSpace.CS_sRGB));
226 		}
227 
228 		// don't try to make a color with parameters outside of the allowed range
229 		if (alpha > 1) {
230 			alpha = 1f;
231 
232 		} else if (alpha < 0) {
233 			alpha = 0f;
234 		}
235 
236 		Color color = new Color(rgbSpace,
237 								rgbSpace.fromCIEXYZ(xyzValues),
238 								alpha);
239 		return color;
240 	}
241 
242 	/*** Convert from a wavelength of monochromatic light to an approximate Color
243 	 *
244 	 * @param wavelength an <code>Integer</code> wavelength (in nm)
245 	 * @param alpha The alpha channel component of the returned <code>Color</code>
246 	 *
247 	 * @return color
248 	 * @throws MirkEApplicationException
249 	 */
250 	public static Color wavelengthToColor(Integer wavelength,
251 										  float alpha)
252 	throws MirkEApplicationException, MirkEFileNotFoundException
253 	{
254 
255 		// ensure that alpha is in the interval [0, 1]
256 		if (alpha < 0) {
257 			alpha = 0f;
258 		} else if (alpha > 1) {
259 			alpha = 1f;
260 		}
261 
262 		return xyzToColor(wavelengthToCIE_XYZcomponents(wavelength), alpha);
263 		}
264 
265 	/***
266      * @param observableToMeanValueMap
267 	 * @return a representative <code>Color</code> for the observable
268 	 * @throws MirkEApplicationException
269 	 */
270 	public static Color observableToMeanValueMapToColor(Map observableToMeanValueMap)
271 	throws MirkEApplicationException ,MirkEFileNotFoundException{
272 		Set entrySet = observableToMeanValueMap.entrySet();
273 		float floatValue = 0;//TODO - remove
274 
275 			Iterator entrySetIterator = entrySet.iterator();
276 			while (entrySetIterator.hasNext()) {
277 				Map.Entry entry = (Map.Entry)entrySetIterator.next();
278 
279 				//String observable = (String)entry.getKey();
280 				Double value = (Double)entry.getValue();
281 				floatValue = (float)value.doubleValue();
282 			}
283 
284 			// TODO - implement
285 			return wavelengthToColor((600),
286 									 (float).5*floatValue);
287 	}
288 
289 	/*** Simple conversion from an array of floats to a Vector
290 
291 		@param values
292 
293 		@return vector
294 		*/
295 	public static Vector toVector(float[] values) {
296 		Vector vector = new Vector();
297 
298 		for (int i=0;i<values.length;i++) {
299 			vector.add(i, new Float(values[i]));
300 		}
301 
302 		return vector;
303 	}
304 }