Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Friday, May 25, 2012

Chemistry Library: Using CIE lib and spectral data together

I've been working on a coding project in my spare time to do various computational things with Chemistry. One of the requirements being that I have a rather complete data set to work with, which includes-- among other things-- The complete spectra of every element possible in the periodic table in all of the various ionization states. This is a result of using CIE Lib to display the spectral power distribution of the line spectrum of the element Neon:

Click on the image for a larger size
Each spectrum is displayed in ascending ionization levels from top to bottom with the topmost line depicting the standard observer, so the neutral Neon atom is at the top, then singly ionized and so-forth. I've seen lots of graphical representations of spectra on the web, and I think I know why Neon seems so weird: They all show the singly-ionized atom, rather  than the neutral atom.

One item to note: In the full-size image, you may notice that the spectral lines are a bit thick, this is because the rendering method used in this application is to sweep the extremes of the visual spectrum and getting a value within a certain tolerance, the other way to render would be to just draw the spectral lines in order, which would give a much more crisp and accurate result. Maybe I'll do that on the next post!

Tuesday, May 22, 2012

CIE Library: Illuminants

And, here's an image of what the illuminants look like using the 1964 observer:



Just a couple quick notes about this image: The spectra are rendered using a gamma of 1.8, which seems to work best, aesthetically, however, I do think they're meant to be rendered with a linear gamma. The first is the standard observer, second is CIE Illuminant A, and the third is D65, after that are the fluorescent illuminants, F1-F12 the first 6 are standard fluorescent illumination the next 3 are high CRI illuminants, and the final 3 are described as three band illuminants.

You'll note in all of the fluorescent samples that the light has strong peaks in the green and blue ranges, and with the exception of the 3-band examples, they all have a relatively weak yellow peak.

The high-cri examples do a little better than the standard fluorescent ones, but not much. I imagine you'd get less metameric failure with that lighting. This also explains the green cast in camera images recorded under fluorescent lighting conditions. It appears F3 and F4 maybe "warm white" while the rest are cool white.

Monday, May 21, 2012

CIE library: The Observers

First, this is not official CIE anything (except the data for standard observer, white points, and illumination sources)

As a test, I wrote a quick program to draw the standard observers from 250nm to 750nm on a window and compare the two, the top observer is the 1964 10° data, the bottom observer is the 1931 2° data. This is approximately how you perceive the spectrum. The colors have been converted from the CIEXYZ color space to the sRGB color space, and have been mapped using a source gamma of 1.8, which is likely incorrect, but gives a nice display for me.


This was a quickie, and I'm sure I could get a better rendering, but that wasn't the focus of this exercise. and yes, I realize that 250-750 is way overkill for these, but this gets into all of the UV and Near IR ranges common in such sources as sunlight.

Sunday, June 20, 2010

Bypassing the Property Grid's Sort Order

While working on a programming project one of the things I wanted to include was the ability to list out the values in the collection in the same way the array lists its items.

Normally, the collection displays an ellipsis button, allowing the user to manipulate the collection, but does not allow the user to expand the list of items like an array does. I figured this would be very simple to add. The .NET framework provides a base class for an object called a TypeConverter. The TypeConverter allows objects of various types to be translated to and from various representations.


Beyond that, the TypeConverter can supply a list of standard values (Enumerators use this, which allows the property grid to display a drop-down list containing the various valid values.) The TypeConverter can also supply an editor class for the type (You see this in form designers all the time, the font dialog, the drop-down for colors, the drop-down for for docking, etc...) Finally, the type converter can also supply a list of properties that the object can display as child properties of a property. It is this that I will focus on:

public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
List<String> lst = (List<String>)value;
ListItemDescriptor[] props = new ListItemDescriptor[lst.Count];

for (int i = 0; i < lst.Count; i++)
props[i] = new ListItemDescriptor(i);

return new PropertyDescriptorCollection(props);
}

The above code demonstrates how the properties are provided by the TypeDescriptor. Using the above code results in the following list in the grid:
Far from optimal for dealing with a list of items. The list is sorted alphabetically. But arrays seem to sort by index. That was what I wanted, so I began spelunking through the reference source code of the .NET framework. Examining the Array code and ArrayConverter code revealed nothing. They were doing essentially what I was doing. I then explored the grid. It appears the PropertyGrid itself considers an array a special case and sorts the items by index. That is no use to me. 
Using the sort method of the PropertyDescriptorCollection object does nothing, since the grid will always override it with the user's sort preference. So, how to sort the items by index?
The secret is in the property descriptor collection. Replacing the return statement above with the following:


return new ListPropertyDescriptorCollection(props);

The following listing shows the ListPropertyDescriptorCollection class that does the magic:
private class ListPropertyDescriptorCollection : PropertyDescriptorCollection
{ 
    public ListPropertyDescriptorCollection(PropertyDescriptor[] props)
    : base(props)
   {
  
    }

    public override PropertyDescriptorCollection Sort
    (System.Collections.IComparer comparer) 
   { 
        if (comparer.GetType().Name == "DisplayNameSortComparer") 
       { 
            ListItemDescriptor.ListItemDescriptorSortComparer comp = 
             new ListItemDescriptor.ListItemDescriptorSortComparer(); 
            return Sort(comp); 
       } 
         else 
       { 
            return base.Sort(comparer);
       }
    }
 }


The code that performs the trick should be rather self-evident:

ListItemDescriptor.ListItemDescriptorSortComparer comp = new ListItemDescriptor.ListItemDescriptorSortComparer();
 return Sort(comp);

Two lines of code in this function do all that is necessary to force the numeric sort. The comparer in this case compares the indicies of the descriptors, causing the sort function to sort by the numeric index. This completely replaces any sort function used with the desired sort, thereby forcing a sort by index. 


 

Sunday, April 04, 2004

Windows Messages

I'm a windows programmer by trade. While working on the batch processor for my photo sharing website, I stumbled upon an interesting feature of windows, Custom Error messages.

If you look at the FormatMessage function, you'll notice it can take an HMODULE to load the message from. But how are these messages created?

The messages are in a special format, compiled by the message compiler (mc.exe)

Each message takes the following form:


MessageId = [ID Number]
Severity = [Severity Code]
Facility = [Facility Name]
SymbolicName = [Identifier]
Language=[Language Name]
[Message Text]
.


For example, the following is a message indicating (for the Event Log) that a service has started:


MessageId = 0x01
Severity = Success
SymbolicName = DPAOL_MSG_SERVICE_STARTED
Language=English
Service Started
.


Most of the specifics are in the MSDN Library.

When you run the compiler on the message, it creates a resource file, a header file, and a binary file, which contains all of your messages. This can be handy for those of you who want to provide users of your library better information.

In the beginning of the this post, I mentioned something about the event log. As it turns out, the event log uses this same mechanism to build it's text information for each of the event entries. Otherwise, it complains, quite verbosely about not being able to read the text for the event ID. More on that later.