Index: sansrealspace/src/realspace/VolumeCanvas.py
===================================================================
--- sansrealspace/src/realspace/VolumeCanvas.py	(revision f98961f9a4d60a9e7e2b4f4701060b8e824bf549)
+++ sansrealspace/src/realspace/VolumeCanvas.py	(revision 3c7569637575e6744d9806b177d81106617f5924)
@@ -214,6 +214,38 @@
         self.hasPr = False        
         
+    def addObject(self, shapeDesc, id = None):
+        """
+            Adds a real-space object to the canvas.
+        
+            @param shapeDesc: object to add to the canvas [ShapeDescriptor]
+            @param id: string handle for the object [string] [optional]
+            @return: string handle for the object
+        """
+        # If the handle is not provided, create one
+        if id == None:
+            id = shapeDesc.params["type"]+str(self.shapecount)
+         
+        # Self the order number
+        shapeDesc.params['order'] = self.shapecount
+        # Store the shape in a dictionary entry associated
+        # with the handle
+        self.shapes[id] = shapeDesc
+        self.shapecount += 1
+
+        #model changed, need to recalculate P(r)
+        self.hasPr = False
+
+        return id
+            
+    
     def add(self, shape, id = None):
         """
+            The intend of this method is to eventually be able to use it
+            as a factory for the canvas and unify the simulation with the
+            analytical solutions. For instance, if one adds a cylinder and
+            it is the only shape on the canvas, the analytical solution
+            could be called. If multiple shapes are involved, then 
+            simulation has to be performed.
+        
             @param shape: name of the object to add to the canvas [string]
             @param id: string handle for the object [string] [optional]
Index: sansrealspace/src/realspace/test/simulation_stimuli.py
===================================================================
--- sansrealspace/src/realspace/test/simulation_stimuli.py	(revision ba1d1e9d2a812317a3694cc34f831cb9178b9f54)
+++ sansrealspace/src/realspace/test/simulation_stimuli.py	(revision 3c7569637575e6744d9806b177d81106617f5924)
@@ -160,4 +160,26 @@
             except:
                 report.log = "GetIq: bad value for Iq "+str(value)
+            
+            report.trace = "I(q) = %g" % value
+            return canvas, report
+    
+    class GetIq2DStimulus(Stimulus):
+        """Calculate I(q)"""
+
+        frequency = 1.0
+        
+        def __call__(self, canvas):
+            report = generator.StimulusReport(tag=self.name)
+            
+            # Check that a float is returned
+            # Validation testing will be done elsewhere
+            value = canvas.getIq2D(0.01,0.01)
+            
+            # Check that it is in the list of objects
+            try:
+                float(value)
+                report.passed = 1
+            except:
+                report.log = "GetIq2D: bad value for Iq "+str(value)
             
             report.trace = "I(q) = %g" % value
Index: sansrealspace/src/realspace/test/utest_oriented.py
===================================================================
--- sansrealspace/src/realspace/test/utest_oriented.py	(revision f98961f9a4d60a9e7e2b4f4701060b8e824bf549)
+++ sansrealspace/src/realspace/test/utest_oriented.py	(revision 3c7569637575e6744d9806b177d81106617f5924)
@@ -59,4 +59,47 @@
         sim_val = self.model.getIq2D(0.1, 0.1)
         self.assert_( math.fabs(sim_val/ana_val-1.0)<0.1 )
+        
+class TestCylinderAddObject(unittest.TestCase):
+    """ Tests for oriented (2D) systems """
+        
+    def setUp(self):
+        """ Set up cylinder model """
+        from sans.models.CylinderModel import CylinderModel
+        radius = 5
+        length = 40
+        density = 20
+    
+        # Analytical model
+        self.ana = CylinderModel()
+        self.ana.setParam('scale', 1.0)
+        self.ana.setParam('contrast', 1.0)
+        self.ana.setParam('background', 0.0)
+        self.ana.setParam('radius', radius)
+        self.ana.setParam('length', length)
+    
+        # Simulation model
+        self.model = VolumeCanvas.VolumeCanvas()
+        cyl = VolumeCanvas.CylinderDescriptor()
+        self.handle = self.model.addObject(cyl)
+        self.model.setParam('lores_density', density)
+        self.model.setParam('%s.radius' % self.handle, radius)
+        self.model.setParam('%s.length' % self.handle, length)
+        self.model.setParam('scale' , 1.0)
+        self.model.setParam('%s.contrast' % self.handle, 1.0)
+        self.model.setParam('background' , 0.0)
+    
+    def testalongY(self):
+        """ Testing cylinder along Y axis """
+        self.ana.setParam('cyl_theta', math.pi/2.0)
+        self.ana.setParam('cyl_phi', math.pi/2.0)
+        
+        self.model.setParam('%s.orientation' % self.handle, [0,0,0])
+        
+        ana_val = self.ana.runXY([0.1, 0.2])
+        sim_val = self.model.getIq2D(0.1, 0.2)
+        #print ana_val, sim_val, sim_val/ana_val
+        
+        self.assert_( math.fabs(sim_val/ana_val-1.0)<0.05 )
+        
         
 class TestCylinder(unittest.TestCase):
