Index: calculatorview/src/sans/perspectives/calculator/gen_scatter_panel.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/gen_scatter_panel.py	(revision 3cfa760829c868841dfd6c4825fbd750fe77ac12)
+++ calculatorview/src/sans/perspectives/calculator/gen_scatter_panel.py	(revision dbc01f27eae0cc56b6db9df1ceb9dbd3d3910a95)
@@ -353,5 +353,5 @@
         x_in = n_qbins * n_pixs / 100000
         # magic equation: not very accurate
-        etime = 0.00001 + 0.085973 * x_in
+        etime = 1.0 + 0.14 * x_in
         return int(etime)
         
@@ -526,11 +526,4 @@
             else:
                 raise
-            for name, _, unit in  self.parameters:
-                if name.GetLabelText() == 'background':
-                    if is_pdbdata:
-                        unit.SetLabel('[A^(2)]')
-                    else:
-                        unit.SetLabel('[1/cm]')
-                    break
             self._set_sld_data_helper(True)
         except:
@@ -575,6 +568,9 @@
         Draw 3D sld profile
         """
+        color_dic = {'H':'blue', 'D':'purple', 'N': 'orange', 
+                     'O':'red', 'C':'green', 'Other':'k'}
         graph_title = self.file_name
         graph_title += "   3D SLD Profile "
+        
         flag = self.parent.check_omfpanel_inputs()
         if not flag:
@@ -595,4 +591,5 @@
         add_icon(self.parent, frame)
         panel = frame.plotpanel
+        
         try:
             # mpl >= 1.0.0
@@ -606,4 +603,5 @@
                 logging.error("PlotPanel could not import Axes3D")
                 raise
+            
         marker = ','
         m_size = 2
@@ -622,4 +620,6 @@
         is_nonzero = sld_tot > 0.0  
         is_zero = sld_tot == 0.0  
+        
+        # Plot null points
         if is_zero.any():
             ax.plot(pos_x[is_zero], pos_z[is_zero], pos_y[is_zero], marker, 
@@ -632,8 +632,20 @@
             sld_my = sld_my[is_nonzero]
             sld_mz = sld_mz[is_nonzero]
-
-        ax.plot(pos_x, pos_z, pos_y, 
-                marker, c="k", 
-                alpha=0.5, markeredgecolor="k", markersize=m_size) 
+        
+        # Plot selective points in color
+        for key in color_dic.keys():
+            chosen_color = output.pix_symbol == key
+            other_color = numpy.ones(len(output.pix_symbol), dtype='bool')
+            if chosen_color.any():
+                other_color = other_color  & (chosen_color != True)
+                color = color_dic[key]
+                ax.plot(pos_x[chosen_color], pos_z[chosen_color], 
+                        pos_y[chosen_color], marker, c=color, alpha=0.5, 
+                        markeredgecolor=color, markersize=m_size, label=key) 
+        # Plot All others        
+        if other_color.any():
+            ax.plot(pos_x[other_color], pos_z[other_color], pos_y[other_color], 
+                    marker, c="k", alpha=0.5, markeredgecolor="k", 
+                    markersize=m_size, label="Other") 
         
         if has_arrow and len(pos_x) > 0:     
@@ -643,6 +655,4 @@
                 draw w/arrow
                 """
-                #frame.SetSize(wx.Size(650, 570))
-                #event.Skip()
                 max_mx = max(numpy.fabs(sld_mx))
                 max_my = max(numpy.fabs(sld_my))
@@ -679,6 +689,5 @@
                                                   mutation_scale=10, lw=1, 
                                                   arrowstyle="->", alpha = 0.5)
-                        ax.add_artist(arrows)
-                        
+                        ax.add_artist(arrows) 
                 except:
                     pass 
@@ -701,4 +710,6 @@
         ax.set_ylabel('z ($\A%s$)'% output.pos_unit)
         ax.set_zlabel('y ($\A%s$)'% output.pos_unit)
+        if output.pix_type == 'atom':
+            ax.legend(loc='upper left', prop={'size':10})
         num_graph = str(self.graph_num)
         frame.SetTitle('Graph %s: %s'% (num_graph, graph_title))        
@@ -743,6 +754,6 @@
             return
         try:
-            vol = self.parent.get_pix_volume()
-            self.model.set_pixel_volume(vol)
+            #vol = self.parent.get_pix_volumes()
+            #self.model.set_pixel_volumes(vol)
             self.model.set_sld_data(self.sld_data)
             self.set_input_params()
@@ -754,5 +765,5 @@
             
             cal_out = CalcGen(input=[self.data.qx_data, 
-                                     self.data.qy_data,i_out], 
+                                     self.data.qy_data, i_out], 
                               completefn=self.complete, 
                               updatefn=self._update)
@@ -1043,14 +1054,11 @@
         return self.sld_data
     
-    def get_pix_volume(self):
+    def get_pix_volumes(self):
         """
         Get the pixel volume
         """
-        val = 1
-        if self.sld_data.pix_type == 'pixel':
-            for lst in self.stepsize:
-                val *= float(lst[1].GetValue())
-        
-        return numpy.fabs(val)
+        vol = self.sld_data.vol_pix
+        
+        return vol
                 
     def _get_other_val(self):  
@@ -1270,4 +1278,5 @@
             ctl = InputTextCtrl(self, -1, size=(_BOX_WIDTH, 20),
                                 style=wx.TE_PROCESS_ENTER)
+            ctl.Bind(wx.EVT_TEXT, self._onstepsize )
             ctl.SetValue(format_number(value, True))
             ctl.Enable(not is_data)
@@ -1387,5 +1396,5 @@
                     ctr_list[1].SetValue(format_number(mean_val, True))
                     ctr_list[1].Enable(enable)
-                    ctr_list[2].SetLabel("[" + sld_data.sld_unit + "]")
+                    #ctr_list[2].SetLabel("[" + sld_data.sld_unit + "]")
                     break   
 
@@ -1483,4 +1492,31 @@
         return flag
     
+    def _onstepsize(self, event):
+        """
+        On stepsize event
+        """
+        flag = True
+        if event != None:
+            event.Skip()
+            ctl = event.GetEventObject()
+            ctl.SetBackgroundColour("white")
+
+        if flag and not self.sld_data.is_data:#ctl.IsEnabled():
+            s_size = 1.0
+            try:
+                for item in self.stepsize:
+                    s_val = float(item[1].GetValue())
+                    if s_val <= 0:
+                        item[1].SetBackgroundColour("pink")
+                        ctl.Refresh()
+                        return
+                    if numpy.isfinite(s_val):
+                        s_size *= s_val
+                self.sld_data.set_pixel_volumes(s_size)
+            except:
+                pass
+        ctl.Refresh()
+  
+         
     def set_npts_from_slddata(self):
         """
@@ -1759,9 +1795,9 @@
         return n_pix
     
-    def get_pix_volume(self):
+    def get_pix_volumes(self):
         """
         Get a pixel volume
         """
-        vol = self.omfpanel.get_pix_volume()
+        vol = self.omfpanel.get_pix_volumes()
         return vol
     
Index: calculatorview/src/sans/perspectives/calculator/load_thread.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/load_thread.py	(revision dbc5dc9b21e953e43e7d6a054b2231a04fd6ae84)
+++ calculatorview/src/sans/perspectives/calculator/load_thread.py	(revision dbc01f27eae0cc56b6db9df1ceb9dbd3d3910a95)
@@ -3,5 +3,4 @@
 """
 import time
-import wx
 from data_util.calcthread import CalcThread
 from sans.dataloader.loader import Loader
Index: calculatorview/src/sans/perspectives/calculator/media/gen_sans_help.html
===================================================================
--- calculatorview/src/sans/perspectives/calculator/media/gen_sans_help.html	(revision 54d6c3e11b32b554f9de763e0a3772f24ae8645f)
+++ calculatorview/src/sans/perspectives/calculator/media/gen_sans_help.html	(revision dbc01f27eae0cc56b6db9df1ceb9dbd3d3910a95)
@@ -115,10 +115,8 @@
 For example, both values are 0.5 for unpolarized neutrons.
 <br>
-*Note II: The unit of intensity calculated from .sld, .omf, or .txt files is 1/cm, otherwise
-it is &#197;<sup>2</sup>. (In the first equation above, the V is set to 1.)
-<br>
-*Note III: This computation is totally based on the pixel (or atomic) data fixed
+*Note II: This computation is totally based on the pixel (or atomic) data fixed
 in the xyz coordinates. Thus no angular orientational averaging is considered.
 <br>
-*Note IV: For the nuclear scattering length density, only the real component is taken account.
+*Note III: For the nuclear scattering length density, only the real component is taken account.
+<br>
 </body>
Index: sanscalculator/src/sans/calculator/sans_gen.py
===================================================================
--- sanscalculator/src/sans/calculator/sans_gen.py	(revision d7b69130a29f8f8b3d8bf726d21ab5fb39feaad6)
+++ sanscalculator/src/sans/calculator/sans_gen.py	(revision dbc01f27eae0cc56b6db9df1ceb9dbd3d3910a95)
@@ -5,4 +5,5 @@
 import sans.models.sans_extension.sld2i as mod
 from periodictable import formula
+from periodictable import nsf
 import numpy
 import os
@@ -11,4 +12,6 @@
 MFactor_mT = 2.3164E-9
 METER2ANG = 1.0E+10
+#Avogadro constant [1/mol]
+NA = 6.02214129e+23
 
 def mag2sld(mag, v_unit=None):
@@ -48,5 +51,5 @@
         self.data_my = None
         self.data_mz = None
-        self.volume = 1000 #[A^3]
+        self.data_vol = None #[A^3]
         ## Name of the model
         self.name = "GenSAS"
@@ -69,9 +72,12 @@
         self.fixed=[]
         
-    def set_pixel_volume(self, volume):     
+    def set_pixel_volumes(self, volume):     
         """
         Set the volume of a pixel in (A^3) unit
-        """
-        self.volume = volume
+        :Param volume: pixel volume [float]
+        """
+        if self.data_vol == None:
+            raise
+        self.data_vol = volume
         
     def _gen(self, x, y, i):
@@ -87,10 +93,11 @@
         model = mod.new_GenI(len_x, self.data_x, self.data_y, self.data_z, 
                              self.data_sldn, self.data_mx, self.data_my, 
-                             self.data_mz, self.params['Up_frac_in'], 
+                             self.data_mz, self.data_vol,
+                             self.params['Up_frac_in'], 
                              self.params['Up_frac_out'], 
                              self.params['Up_theta'])
+
         mod.genicom(model, len_q, x, y, i)
-        return  self.params['scale'] * i * self.volume \
-                + self.params['background']
+        return  self.params['scale'] * i + self.params['background']
         
     def set_sld_data(self, sld_data=None):   
@@ -107,4 +114,5 @@
         self.data_my = sld_data.sld_my
         self.data_mz = sld_data.sld_mz
+        self.data_vol = sld_data.vol_pix
         
     def getProfile(self):
@@ -126,5 +134,5 @@
             y_in = numpy.zero_like(x[0])
             # 1D I is found at y =0 in the 2D pattern
-            return self._gen(x[0],y_in, i_out )
+            return self._gen(x[0], y_in, i_out )
         else:
             msg = "Q must be given as list of qx's and qy's"
@@ -183,4 +191,5 @@
         self.mz = None
         self.sld_n = None
+        self.vol_pix = None
         self.output = None
         self.omfdata = None
@@ -443,5 +452,5 @@
     type = ["pdb files (*.PDB, *.pdb)|*.pdb"]
     ## List of allowed extensions
-    ext = ['.pdb', '.PDB']
+    ext = ['.pdb', '.PDB']   
     
     def read(self, path):
@@ -462,4 +471,5 @@
         sld_my = numpy.zeros(0)
         sld_mz = numpy.zeros(0)
+        vol_pix = numpy.zeros(0)
         pix_symbol = numpy.zeros(0)
         try:
@@ -498,11 +508,15 @@
                         pos_z = numpy.append(pos_z, _pos_z)
                         try:
-                            #from periodictable import nsf
-                            #val = nsf.neutron_sld(atom_name)
-                            val = formula(atom_name).atoms.keys()[0].neutron.b_c
                             # sld in Ang unit (from fm)
-                            val = float(val)
-                            val *= 1.0e-5
+                            #val = formula(atom_name).atoms.keys()[0].neutron.b_c
+                            #val *= 1.0e-5
+                            val = nsf.neutron_sld(atom_name)[0]
+                            # sld in Ang^-2 unit
+                            val *= 1.0e-6
                             sld_n = numpy.append(sld_n, val)
+                            atom = formula(atom_name)
+                            # cm to A units
+                            vol = 1.0e+24 * atom.mass / atom.density / NA
+                            vol_pix = numpy.append(vol_pix, vol)
                         except:
                             print "Error: set the sld of %s to zero"% atom_name
@@ -525,5 +539,6 @@
             output.set_pixel_symbols(pix_symbol)
             output.set_nodes()
-            output.sld_unit = 'A'
+            output.set_pixel_volumes(vol_pix)
+            output.sld_unit = '1/A^(2)'
             return output
         except:
@@ -561,45 +576,35 @@
         :raise ValueError: when the length of the data vectors are inconsistent
         """
-        pos_x = numpy.zeros(0)
-        pos_y = numpy.zeros(0)
-        pos_z = numpy.zeros(0)
-        sld_n = numpy.zeros(0)
-        sld_mx = numpy.zeros(0)
-        sld_my = numpy.zeros(0)
-        sld_mz = numpy.zeros(0)
+        
+
         try:
-            input_f = open(path, 'rb')
-            buff = input_f.read()
-            lines = buff.split('\n')
-            input_f.close()
-            for line in lines:
-                toks = line.split()
-                try:
-                    _pos_x = float(toks[0])
-                    _pos_y = float(toks[1])
-                    _pos_z = float(toks[2])
-                    _sld_n = float(toks[3])
-                    _sld_mx = float(toks[4])
-                    _sld_my = float(toks[5])
-                    _sld_mz = float(toks[6])
-
-                    pos_x = numpy.append(pos_x, _pos_x)
-                    pos_y = numpy.append(pos_y, _pos_y)
-                    pos_z = numpy.append(pos_z, _pos_z)
-                    sld_n = numpy.append(sld_n, _sld_n)
-                    sld_mx = numpy.append(sld_mx, _sld_mx)
-                    sld_my = numpy.append(sld_my, _sld_my)
-                    sld_mz = numpy.append(sld_mz, _sld_mz)
-                except:
-                    # Skip non-data lines
-                    pass
+            input_f = numpy.loadtxt(path, dtype='float', skiprows=1, 
+                                    ndmin=1, unpack=True)
+            pos_x = numpy.array(input_f[0])
+            pos_y = numpy.array(input_f[1])
+            pos_z = numpy.array(input_f[2])
+            sld_n = numpy.array(input_f[3])
+            sld_mx = numpy.array(input_f[4])
+            sld_my = numpy.array(input_f[5])
+            sld_mz = numpy.array(input_f[6])
+            ncols = len(input_f)
+            if ncols == 8:
+                vol_pix = numpy.array(input_f[7])
+            elif ncols == 7:
+                 vol_pix = None
+            else:
+                raise        
             pos_x -= (min(pos_x) + max(pos_x)) / 2.0
             pos_y -= (min(pos_y) + max(pos_y)) / 2.0
             pos_z -= (min(pos_z) + max(pos_z)) / 2.0
 
-            output = MagSLD(pos_x, pos_y, pos_z, sld_n, sld_mx, sld_my, sld_mz)
+            output = MagSLD(pos_x, pos_y, pos_z, sld_n, 
+                            sld_mx, sld_my, sld_mz)
+
             output.filename = os.path.basename(path)
             output.set_pix_type('pixel')
             output.set_pixel_symbols('pixel')
+            if vol_pix != None:
+                output.set_pixel_volumes(vol_pix)
             return output
         except:
@@ -621,4 +626,5 @@
         y_val = data.pos_y
         z_val = data.pos_z
+        vol_pix = data.vol_pix
         
         length = len(x_val)
@@ -639,10 +645,10 @@
         out = open(path, 'w')
         # First Line: Column names
-        out.write("X  Y  Z  SLDN  SLDMx  SLDMy  SLDMz")
+        out.write("X  Y  Z  SLDN SLDMx  SLDMy  SLDMz VOLUMEpix")
         for ind in range(length):
-            out.write("\n%g  %g  %g  %g  %g  %g  %g" % (x_val[ind], y_val[ind], 
+            out.write("\n%g  %g  %g  %g  %g  %g  %g %g" % (x_val[ind], y_val[ind], 
                                                     z_val[ind], sld_n[ind], 
                                                     sld_mx[ind], sld_my[ind], 
-                                                    sld_mz[ind]))  
+                                                    sld_mz[ind], vol_pix[ind]))  
         out.close()       
             
@@ -749,5 +755,5 @@
     
     def __init__(self, pos_x, pos_y, pos_z, sld_n=None, 
-                 sld_mx=None, sld_my=None, sld_mz=None):
+                 sld_mx=None, sld_my=None, sld_mz=None, vol_pix=None):
         """
         Init for mag SLD
@@ -773,4 +779,5 @@
         self.sld_my = sld_my
         self.sld_mz = sld_mz
+        self.vol_pix = vol_pix
         self.sld_m = None
         self.sld_phi = None
@@ -851,4 +858,18 @@
         else:
             self.pix_symbol = symbol
+            
+    def set_pixel_volumes(self, vol):  
+        """
+        Set pixel volumes
+        :Params pixel: str; pixel or atomic symbol, or array of strings
+        """
+        if self.sld_n == None:
+            return
+        if vol.__class__.__name__ == 'ndarray':
+            self.vol_pix = vol
+        elif vol.__class__.__name__.count('float') > 0:
+            self.vol_pix = numpy.repeat(vol, len(self.sld_n))
+        else:
+            self.vol_pix = None
 
     def get_sldn(self):
@@ -913,4 +934,8 @@
                         self.zstepsize = numpy.fabs(z_pos - zpos_pre)
                         break
+                #default pix volume
+                self.vol_pix = numpy.ones(len(self.pos_x))
+                vol = self.xstepsize * self.ystepsize * self.zstepsize
+                self.set_pixel_volumes(vol)
                 self.has_stepsize = True
             except:
@@ -918,4 +943,5 @@
                 self.ystepsize = None
                 self.zstepsize = None
+                self.vol_pix = None
                 self.has_stepsize = False
         else:
@@ -1006,4 +1032,4 @@
         
 if __name__ == "__main__": 
-    #test()
+    test()
     test_load()
