def test2(self):
     "GlobalGeometer: instrument with one moderator given abs position"
     import elements
     from Geometer import Geometer
     instrument = elements.ElementContainer( "instrument" )
     moderator = elements.moderator( "moderator", 100., 100., 10. ) 
     instrument.addElement( moderator )
         
     instrument_geometer = Geometer( instrument )
     instrument_geometer.register( moderator, (0,0,-5), (0,0,0) )
     instrument_geometer.finishRegistration()
     
     local_geometers = [ instrument_geometer ]
     global_geometer = GlobalGeometer( instrument, local_geometers )
     
     mod_pos = global_geometer.position( moderator ) / meter
     self.assertAlmostEqual( mod_pos[0], 0 )
     self.assertAlmostEqual( mod_pos[1], 0 )
     self.assertAlmostEqual( mod_pos[2], -5 )
     return
    def test3(self):
        "GlobalGeometer: instrument with one moderator and monitors given relative position"
        import elements
        from Geometer import Geometer
        instrument = elements.ElementContainer( "instrument" )
        moderator = elements.moderator( "moderator", 100., 100., 10. ) 
        instrument.addElement( moderator )
                             
        monitor1 = elements.monitor( "monitor1", 100., 100., 10. ) 
        instrument.addElement( monitor1 )
        monitor2 = elements.monitor( "monitor2", 100., 100., 10. ) 
        instrument.addElement( monitor2 )
        
        instrument_geometer = Geometer( instrument )
        instrument_geometer.register( moderator, (0,0,-5), (0,0,0))
        instrument_geometer.register( monitor1, (0,0,-3), (0,0,0))
        instrument_geometer.register( monitor2, (0,0,2), (0,0,0), relative = monitor1 )
        instrument_geometer.finishRegistration()

        local_geometers = [ instrument_geometer ]

        global_geometer = GlobalGeometer( instrument, local_geometers )
        
        moderator_pos = global_geometer.position( moderator ) / meter
        self.assertAlmostEqual( moderator_pos[0], 0 )
        self.assertAlmostEqual( moderator_pos[1], 0 )
        self.assertAlmostEqual( moderator_pos[2], -5 )
        
        monitor1_pos = global_geometer.position( monitor1 )  / meter
        self.assertAlmostEqual( monitor1_pos[0], 0 )
        self.assertAlmostEqual( monitor1_pos[1], 0 )
        self.assertAlmostEqual( monitor1_pos[2], -3 )
        
        monitor2_pos = global_geometer.position( monitor2 ) / meter
        self.assertAlmostEqual( monitor2_pos[0], 0 )
        self.assertAlmostEqual( monitor2_pos[1], 0 )
        self.assertAlmostEqual( monitor2_pos[2], -1 )
        return
class CompositeScatterer:
    

    def __init__(
        self, shape = None,
        max_multiplescattering_loops_among_scatterers = None,
        max_multiplescattering_loops_interactM_path1 = None,
        min_neutron_probability = None,
        ):
        from Geometer import Geometer
        self.geometer = Geometer()
        self._elements = []
        self._shape = shape
        self.setMultipleScatteringParams(
            max_multiplescattering_loops_interactM_path1 = \
                max_multiplescattering_loops_interactM_path1,
            max_multiplescattering_loops_among_scatterers = \
                max_multiplescattering_loops_among_scatterers,
            min_neutron_probability = min_neutron_probability,
            )
        return
    

    def setMultipleScatteringParams(
        self, 
        max_multiplescattering_loops_among_scatterers = None,
        max_multiplescattering_loops_interactM_path1 = None,
        min_neutron_probability = None,
        ):
        self.max_multiplescattering_loops_among_scatterers = max_multiplescattering_loops_among_scatterers or 5
        self.max_multiplescattering_loops_interactM_path1 = max_multiplescattering_loops_interactM_path1 or 1
        self.min_neutron_probability = min_neutron_probability or 0.
        return


    def addElement(self, element, position = (0,0,0), orientation = (0,0,0) ):
        self._elements.append(element)
        self.geometer.register(element, position, orientation)
        return


    def elements(self): return self._elements


    def identify(self, visitor): return visitor.onCompositeScatterer(self)


    def shape(self):
        if self._shape is None:
            from geometry.operations import unite
            self._shape = unite( *[self._getElementShape(e)
                                   for e in self.elements() ] )
            pass
        return self._shape


    def _getElementShape(self, e):
        s = e.shape()
        g = self.geometer
        position = g.position(e)
        orientation = g.orientation(e)
        import geometry
        r = geometry.operations.rotate(s, orientation)
        t = geometry.operations.translate(r, position)
        return t
    

    pass # end of CompositeScatterer
    def test4(self):
        "GlobalGeometer: instrument with layers"
        import elements
        from Geometer import Geometer
        
        instrument = elements.instrument( "instrument" )
        
        moderator = elements.moderator( "moderator", 100., 100., 10. ) 
        instrument.addElement( moderator ) 
        
        monitor1 = elements.monitor( "monitor1", 100., 100., 10. ) 
        instrument.addElement( monitor1 )
        
        sample = elements.sample( "sample" )
        instrument.addElement( sample)
        
        detectorSystem = elements.detectorSystem( "detectorSystem" )
        instrument.addElement( detectorSystem )

        local_geometers = []
        
        detectorSystem_geometer = Geometer( detectorSystem )
        local_geometers.append( detectorSystem_geometer )
        
        #add 8X10 detectors by brute force
        for i in range(10):
            
            detpack = elements.detectorPack( "detpack%s" % i )
            detpack_geometer = Geometer( detpack )

            for j in range(8):
                name = "det%s"%j
                det = elements.detector(name)
                exec 'det_%s_%s = det' % (i,j)
                detpack.addElement( det )
                detpack_geometer.register( det, (j-3.5, 0, 0 ), (0,0,0) )
                continue
            
            detpack_geometer.finishRegistration()
            
            detectorSystem.addElement( detpack)
            local_geometers.append( detpack_geometer )
            
            detectorSystem_geometer.register( detpack, (10*i, 0, 0), (0,0,0) )
            continue

        detectorSystem_geometer.finishRegistration()

        instrument_geometer = Geometer( instrument )
        instrument_geometer.register( moderator, (0,0,-5), (0,0,0) )
        instrument_geometer.register( sample, (0,0,0), (0,0,0) )
        instrument_geometer.register( detectorSystem, (0,0,0), (0,0,0) )
        instrument_geometer.register( monitor1, (0,0,-3), (0,0,0) )
        instrument_geometer.finishRegistration()

        local_geometers.append( instrument_geometer )

        global_geometer = GlobalGeometer( instrument, local_geometers )
        
        moderator_pos = global_geometer.position( moderator ) / meter
        self.assertAlmostEqual( moderator_pos[0], 0 )
        self.assertAlmostEqual( moderator_pos[1], 0 )
        self.assertAlmostEqual( moderator_pos[2], -5 )

        detector00_pos = global_geometer.position(
            'detectorSystem/detpack0/det0') / meter
        self.assertAlmostEqual( detector00_pos[0], -3.5 )
        self.assertAlmostEqual( detector00_pos[1], 0 )
        self.assertAlmostEqual( detector00_pos[2], 0 )

        moderator2detector00 = global_geometer.displacement(
            moderator, 'detectorSystem/detpack0/det0' ) / meter
        self.assertAlmostEqual( moderator2detector00[0], -3.5 )
        self.assertAlmostEqual( moderator2detector00[1], 0 )
        self.assertAlmostEqual( moderator2detector00[2], 5 )
        
        return