Esempio n. 1
0
 def set_orientation_axis(self, orientationAxis):
     """
     Sets orientation axis value.
     
     :Parameters:
        #. orientationAxis (dict): The axis to align the group axis with.
           If key is fixed, value must be a list, tuple or a numpy.array of a vector such as [X,Y,Z]
           if Key is symmetry, in this case the the value must be a list of two items, the first one is a list
           of atoms indexes to compute symmetry axis and the second item must be even 0, 1 or 2 for respectively 
           the first, second and tertiary symmetry axis. 
     """
     assert isinstance(orientationAxis, dict), LOGGER.error("orientationAxis must be a dictionary")
     assert len(orientationAxis) == 1, LOGGER.error("orientationAxis must have a single key")       
     key = orientationAxis.keys()[0]
     val = orientationAxis[key]
     if key == "fixed":
         self.__mustComputeOrientationAxis = False
         assert isinstance(val, (list,set,tuple,np.ndarray)), LOGGER.error("orientationAxis value must be a list")
         if isinstance(val, np.ndarray):
             assert len(val.shape) == 1, LOGGER.error("orientationAxis value must have a single dimension")
         val = list(val)
         assert len(val)==3, LOGGER.error("orientationAxis fixed value must be a vector")
         for v in val:
             assert is_number(v), LOGGER.error("orientationAxis value item must be numbers") 
         val  = np.array([FLOAT_TYPE(v) for v in val], dtype=FLOAT_TYPE) 
         norm = FLOAT_TYPE(np.sqrt(np.sum(val**2)))   
         val /= norm            
     elif key == "symmetry":
         self.__mustComputeOrientationAxis = True
         assert isintance(val, (list, tuple)), LOGGER.error("orientationAxis symmetry value must be a list") 
         assert len(val) == 2, LOGGER.error("orientationAxis symmetry value must be a list of two items")
         val0 = []
         for v in val[0]:
             assert is_integer(v), LOGGER.error("orientationAxis symmetry value list items must be integers") 
             v0 = INT_TYPE(v)
             assert v0>=0, LOGGER.error("orientationAxis symmetry value list items must be positive") 
             val0.append(v0)
         assert len(set(val0))==len(val[0]), LOGGER.error("orientationAxis symmetry value list redundant items indexes found") 
         val0 = np.array(val0, dtype=INT_TYPE)
         val1 = val[1]
         assert is_integer(val1), LOGGER.error("orientationAxis symmetry value second item must be an integer") 
         val1 = INT_TYPE(val1)
         assert val1>=0 and val1<3, LOGGER.error("orientationAxis symmetry value second item must be positive smaller than 3") 
         val = (val0,val1)
     else:
         self.__mustComputeOrientationAxis = None
         raise Exception(LOGGER.error("orientationAxis key must be either 'fixed' or 'symmetry'"))        
     # set orientationAxis
     self.__orientationAxis = {key:val}
Esempio n. 2
0
    def set_indexes(self, indexes):
        """
        Set group atoms index. Indexes redundancy is not checked
        and indexes order is preserved.

        :Parameters:
            #. indexes (list,set,tuple,np.ndarray): The group atoms indexes.
        """
        assert isinstance(indexes,
                          (list, set, tuple, np.ndarray)), LOGGER.error(
                              "indexes must be either a list or a numpy.array")
        if isinstance(indexes, np.ndarray):
            assert len(indexes.shape) == 1, LOGGER.error(
                "each group must be a numpy.ndarray of dimension 1")
        # create group of indexes
        group = []
        for idx in list(indexes):
            assert is_integer(idx), LOGGER.error(
                "group indexes must be integers")
            assert idx >= 0, LOGGER.error(
                "group index must equal or bigger than 0")
            group.append(int(idx))
        # check length
        assert len(group) or isinstance(self, EmptyGroup), LOGGER.error(
            "Group is found to be empty. Use EmptyGroup instead.")
        # create indexes
        self.__indexes = np.array(group, dtype=INT_TYPE)
Esempio n. 3
0
 def append_to_swap_list(self, subList):
     """
     append a sub list to swap list
     
     :Parameters: 
         #. subList (List): The sub-list of atom indexes to append to swapList.
     """
     assert isinstance(subList, (list,tuple)), LOGGER.error("subList must be a list")
     subSL = []
     for num in subList:
         assert is_integer(num), LOGGER.error("subList items must be integers")
         num = INT_TYPE(num)
         assert num>=0, LOGGER.error("subList items must be positive")
         subSL.append(num)
     assert len(set(subSL))==len(subSL), LOGGER.error("swapList items must not have any redundancy")
     assert len(subSL) == self.__swapLength, LOGGER.error("swapList item length must be equal to swapLength")
     # append
     self.__swapList = list(self.__swapList)
     subSL = np.array(subSL, dtype=INT_TYPE)
     self.__swapList.append(subSL)
     self.__swapList = tuple(self.__swapList)
     # set uncollected atoms swapList
     self._remainingAtomsSwapList  = self.__swapList
     # reset collector state
     self._collectorState = None  
Esempio n. 4
0
 def set_order(self, order):
     """
     Set selector groups order.
     
     :Parameters:
         #. order (None, list, set, tuple, numpy.ndarray): The selector order of groups.
     """
     if order is None:
         newOrder = None
     else:
         assert isinstance(order, (list, set, tuple, np.ndarray)), LOGGER.error("order must a instance among list, set, tuple or numpy.ndarray")
         if isinstance(order, np.ndarray):
             assert len(order.shape)==1, LOGGER.error("order numpy.ndarray must have one dimension")
         order = list(order)
         assert len(order)>0, LOGGER.error("order can't be empty")
         newOrder = []
         for idx in order:
             assert is_integer(idx), LOGGER.error("order indexes must be integers")
             idx = int(idx)
             assert idx>=0, LOGGER.error("order indexes must be positive")
             assert idx<len(self.engine.groups), LOGGER.error("order indexes must be smaller than engine's number of groups")
             newOrder.append(idx)
         newOrder = np.array(newOrder, dtype=INT_TYPE)
     # set order
     self.__order = newOrder
     # re-initialize selector
     self.__initialize_selector__()
Esempio n. 5
0
 def set_center(self, center):
     """
     Sets center value.
     
     :Parameters:
        #. center (dict): The center value dictionary. Must have a single key and this can only be 'fixed' or 'indexes'.
           If key is fixed, value must be a list or a numpy.array of a point coordinates such as [X,Y,Z]
           If key is indexes, value must be a list or a numpy array of indexes.
     """
     assert isinstance(center, dict), LOGGER.error("center must be a dictionary")
     assert len(center) == 1, LOGGER.error("center must have a single key")       
     key = center.keys()[0]
     val = center[key]
     assert isinstance(val, (list,set,tuple,np.ndarray)), LOGGER.error("center value must be a list")
     if isinstance(val, np.ndarray):
         assert len(val.shape) == 1, LOGGER.error("center value must have a single dimension")
     assert len(val)>0, LOGGER.error("center value must be a non-zero list.")
     for v in val:
         assert is_number(v), LOGGER.error("center value item must be numbers") 
     if key == "fixed":
         self.__mustCompute = False
         assert len(val) == 3, LOGGER.error("fixed center must have exactly 3 elements corresponding to X,Y and Z coordinates of the center point.")
         val = np.array([FLOAT_TYPE(v) for v in val], dtype=FLOAT_TYPE)
     elif key == "indexes":
         self.__mustCompute = True
         for v in val:
             assert is_integer(v), LOGGER.error("indexes center items be integers")
         val =  np.array([INT_TYPE(v) for v in val], dtype=INT_TYPE)
         for v in val:
             assert v>=0, LOGGER.error("indexes center items be positive integers")            
     else:
         self.__mustCompute = None
         raise Exception(LOGGER.error("center key must be either 'fixed' or 'indexes'"))        
     # set center
     self.__center = {key:val}
Esempio n. 6
0
 def set_adjust_scale_factor(self, adjustScaleFactor):
     """
     Sets adjust scale factor.
     
     :Parameters:
         #. adjustScaleFactor (list, tuple): Used to adjust fit or guess the best scale factor during EMC runtime. 
            It must be a list of exactly three entries.\n
            1. The frequency in number of accepted moves of finding the best scale factor. 
               If 0 frequency is given, it means that the scale factor is fixed.
            2. The minimum allowed scale factor value.
            3. The maximum allowed scale factor value.
     """
     assert isinstance(adjustScaleFactor, (list, tuple)), LOGGER.error('adjustScaleFactor must be a list.')
     assert len(adjustScaleFactor) == 3, LOGGER.error('adjustScaleFactor must be a list of exactly three items.')
     freq  = adjustScaleFactor[0]
     minSF = adjustScaleFactor[1]
     maxSF = adjustScaleFactor[2]
     assert is_integer(freq), LOGGER.error("adjustScaleFactor first item (frequency) must be an integer.")
     freq = INT_TYPE(freq)
     assert freq>=0, LOGGER.error("adjustScaleFactor first (frequency) item must be bigger or equal to 0.")
     assert is_number(minSF), LOGGER.error("adjustScaleFactor second item (minimum) must be a number.")
     minSF = FLOAT_TYPE(minSF)
     assert is_number(maxSF), LOGGER.error("adjustScaleFactor third item (maximum) must be a number.")
     maxSF = FLOAT_TYPE(maxSF)
     assert minSF<=maxSF, LOGGER.error("adjustScaleFactor second item (minimum) must be smaller or equal to third second item (maximum).")
     # set values
     self.__adjustScaleFactorFrequency = freq
     self.__adjustScaleFactorMinimum   = minSF
     self.__adjustScaleFactorMaximum   = maxSF
     # dump to repository
     self._dump_to_repository({'_ExperimentalConstraint__adjustScaleFactorFrequency': self.__adjustScaleFactorFrequency,
                               '_ExperimentalConstraint__adjustScaleFactorMinimum'  : self.__adjustScaleFactorMinimum,
                               '_ExperimentalConstraint__adjustScaleFactorMaximum'  : self.__adjustScaleFactorMaximum})
     # reset constraint
     self.reset_constraint()
Esempio n. 7
0
    def set_order(self, order):
        """
        Set selector groups order.

        :Parameters:
            #. order (None, list, set, tuple, numpy.ndarray): The selector order of groups.
        """
        if order is None:
            newOrder = None
        else:
            assert isinstance(order, (list, set, tuple, np.ndarray)), LOGGER.error("order must a instance among list, set, tuple or numpy.ndarray")
            if isinstance(order, np.ndarray):
                assert len(order.shape)==1, LOGGER.error("order numpy.ndarray must have one dimension")
            order = list(order)
            assert len(order)>0, LOGGER.error("order can't be empty")
            newOrder = []
            for idx in order:
                assert is_integer(idx), LOGGER.error("order indexes must be integers")
                idx = int(idx)
                assert idx>=0, LOGGER.error("order indexes must be positive")
                assert idx<len(self.engine.groups), LOGGER.error("order indexes must be smaller than engine's number of groups")
                newOrder.append(idx)
            newOrder = np.array(newOrder, dtype=INT_TYPE)
        # set order
        self.__order = newOrder
        # re-initialize selector
        self.__initialize_selector__()
Esempio n. 8
0
    def set_swap_list(self, swapList):
        """
        Set the swap-list to exchange atoms position from.

        :Parameters:
            #. swapList (None, List): The list of atoms.\n
               If None is given, no swapping or exchanging will be performed.\n
               If List is given, it must contain lists of atom indexes where
               every sub-list length must be equal to swapLength.
        """
        C = _Container()
        # add container
        if not C.is_container('swapList'):
            C.add_container('swapList')
        # check if swapList already defined
        loc = C.get_location_by_hint(swapList)
        if loc is not None:
            self.__swapList = C.get_value(loc)
        elif swapList is None:
            self.__swapList = ()
        else:
            SL = []
            assert isinstance(
                swapList,
                (list, tuple)), LOGGER.error("swapList must be a list")
            for sl in swapList:
                assert isinstance(
                    sl, (list,
                         tuple)), LOGGER.error("swapList items must be a list")
                subSL = []
                for num in sl:
                    assert is_integer(num), LOGGER.error(
                        "swapList sub-list items must be integers")
                    num = INT_TYPE(num)
                    assert num >= 0, LOGGER.error(
                        "swapList sub-list items must be positive")
                    subSL.append(num)
                assert len(set(subSL)) == len(subSL), LOGGER.error(
                    "swapList items must not have any redundancy")
                if self.swapLength is not None:
                    assert len(subSL) == self.swapLength, LOGGER.error(
                        "swapList item length must be equal to swapLength")
                SL.append(np.array(subSL, dtype=INT_TYPE))
            self.__swapList = tuple(SL)
            # add swapList to container
            C.set_value(container='swapList',
                        value=self.__swapList,
                        hint=swapList)
        # set uncollected atoms swapList
        self._remainingAtomsSwapList = self.__swapList
        # reset collector state
        self._collectorState = None
Esempio n. 9
0
 def set_recur(self, recur):
     """
     Sets the recur value.
     
     :Parameters:
         #. recur (integer): Set the recur value.
            It must be a positive integer.
     """
     assert is_integer(recur), LOGGER.error("recur must be an integer")
     recur = INT_TYPE(recur)
     assert recur >= 0, LOGGER.error("recur must be positive")
     self.__recur = recur
     self.__recurAsSet = recur
Esempio n. 10
0
 def set_axis(self, axis):
     """
     Sets the symmetry axis index to translate along.
     
     :Parameters:
         #. axis (integer): Must be 0,1 or 2 for respectively the main, secondary or tertiary symmetry axis
     """
     assert is_integer(axis), LOGGER.error("rotation symmetry axis must be an integer.")
     axis = INT_TYPE(axis)
     assert axis>=0, LOGGER.error("rotation symmetry axis must be positive.")
     assert axis<=2, LOGGER.error("rotation symmetry axis must be smaller or equal to 2.")
     # convert to radian and store amplitude
     self.__axis = axis
Esempio n. 11
0
 def set_tried(self, value):
     """
     Sets constraint's engine tried moves.
     
     :Parameters:
         #. value (integer): constraint tried moves value
     """
     try:
         value = float(value)
     except:
         raise Exception(LOGGER.error("tried value must be convertible to a number"))
     assert is_integer(value), LOGGER.error("tried value must be integer")
     assert value>=0, LOGGER.error("tried value must be positive")
     self.__tried = int(value)
Esempio n. 12
0
    def set_axis(self, axis):
        """
        Set the symmetry axis index to translate along.

        :Parameters:
            #. axis (integer): Must be 0,1 or 2 for respectively the main,
               secondary or tertiary symmetry axis
        """
        assert is_integer(axis), LOGGER.error("rotation symmetry axis must be an integer.")
        axis = INT_TYPE(axis)
        assert axis>=0, LOGGER.error("rotation symmetry axis must be positive.")
        assert axis<=2, LOGGER.error("rotation symmetry axis must be smaller or equal to 2.")
        # convert to radian and store amplitude
        self.__axis = axis
Esempio n. 13
0
    def set_group_axis(self, groupAxis):
        """
        Sets group axis value.

        :Parameters:
           #. groupAxis (dict): The group axis. Only one key is allowed.
              If key is fixed, value must be a list, tuple or a numpy.array
              of a vector such as [X,Y,Z]. If key is symmetry, in this case
              the group axis is computed as one of the three symmetry axis of
              the group atoms. the value must be even 0, 1 or 2 for
              respectively the first, second and tertiary symmetry axis.
        """
        assert isinstance(groupAxis,
                          dict), LOGGER.error("groupAxis must be a dictionary")
        assert len(groupAxis) == 1, LOGGER.error(
            "groupAxis must have a single key")
        key = groupAxis.keys()[0]
        val = groupAxis[key]
        if key == "fixed":
            self.__mustComputeGroupAxis = False
            assert isinstance(
                val,
                (list, set, tuple,
                 np.ndarray)), LOGGER.error("groupAxis value must be a list")
            if isinstance(val, np.ndarray):
                assert len(val.shape) == 1, LOGGER.error(
                    "groupAxis value must have a single dimension")
            val = list(val)
            assert len(val) == 3, LOGGER.error(
                "groupAxis fixed value must be a vector")
            for v in val:
                assert is_number(v), LOGGER.error(
                    "groupAxis value item must be numbers")
            val = np.array([FLOAT_TYPE(v) for v in val], dtype=FLOAT_TYPE)
            norm = FLOAT_TYPE(np.sqrt(np.sum(val**2)))
            val /= norm
        elif key == "symmetry":
            self.__mustComputeGroupAxis = True
            assert is_integer(val), LOGGER.error(
                "groupAxis symmetry value must be an integer")
            val = INT_TYPE(val)
            assert val >= 0 and val < 3, LOGGER.error(
                "groupAxis symmetry value must be positive smaller than 3")
        else:
            self.__mustComputeGroupAxis = None
            raise Exception(
                LOGGER.error(
                    "groupAxis key must be either 'fixed' or 'symmetry'"))
        # set groupAxis
        self.__groupAxis = {key: val}
Esempio n. 14
0
 def __check_single_weight(self, w):
     """Checks a single group weight tuple format"""
     assert isinstance(w, (list,set,tuple)),LOGGER.error("weights list items must be tuples")
     assert len(w)==2, LOGGER.error("weights list tuples must have exactly 2 items")
     idx  = w[0]
     wgt = w[1]
     assert is_integer(idx), LOGGER.error("weights list tuples first item must be an integer")
     idx = INT_TYPE(idx)
     assert idx>=0, LOGGER.error("weights list tuples first item must be positive")
     assert idx<len(self.__collection), LOGGER.error("weights list tuples first item must be smaller than the number of generators in collection")
     assert is_number(wgt), LOGGER.error("weights list tuples second item must be an integer")
     wgt = FLOAT_TYPE(wgt)
     assert wgt>0, LOGGER.error("weights list tuples first item must be bigger than 0")
     # all True return idx and weight
     return idx, wgt  
Esempio n. 15
0
 def set_maximum_collected(self, maximumCollected):
     """
     Set maximum collected number of atoms allowed.
     
     :Parameters:
         #. maximumCollected (None, Integer): The maximum number allowed of atoms to be 
            removed and collected from the engine. This property is general to the 
            system and checks engine's collected atoms not the number of removed atoms 
            via this generator. If None is given, the remover will not check for the
            number of already removed atoms before attempting a remove.
     """
     if maximumCollected is not None:
         assert is_integer(maximumCollected), LOGGER.error("maximumCollected must be an integer")
         maximumCollected = INT_TYPE(maximumCollected)
         assert maximumCollected>0, LOGGER.error("maximumCollected must be bigger than 0")
     self.__maximumCollected = maximumCollected
Esempio n. 16
0
 def set_swap_length(self, swapLength):
     """
     Set swap length. it will reset swaplist automatically.
 
     :Parameters:
         #. swapLength (Integer): The swap length that defines the length of the group 
            and the length of the every swap sub-list in swapList.
     """   
     assert is_integer(swapLength), LOGGER.error("swapLength must be an integer")
     swapLength = INT_TYPE(swapLength)
     assert swapLength>0, LOGGER.error("swapLength must be bigger than 0")
     self.__swapLength = swapLength
     self.__swapList   = ()
     # set uncollected atoms swapList
     self._remainingAtomsSwapList  = self.__swapList
     # reset collector state
     self._collectorState = None    
Esempio n. 17
0
 def set_center(self, center):
     """
     Sets center value.
     
     :Parameters:
         #. center (dict): The center value dictionary. Must have a single key and this can only be 'fixed' or 'indexes'.
            If key is fixed, value must be a list or a numpy.array of a point coordinates such as [X,Y,Z]
            If key is indexes, value must be a list or a numpy array of indexes.
     """
     assert isinstance(center,
                       dict), LOGGER.error("center must be a dictionary")
     assert len(center) == 1, LOGGER.error("center must have a single key")
     key = center.keys()[0]
     val = center[key]
     assert isinstance(
         val, (list, set, tuple,
               np.ndarray)), LOGGER.error("center value must be a list")
     if isinstance(val, np.ndarray):
         assert len(val.shape) == 1, LOGGER.error(
             "center value must have a single dimension")
     assert len(val) > 0, LOGGER.error(
         "center value must be a non-zero list.")
     for v in val:
         assert is_number(v), LOGGER.error(
             "center value item must be numbers")
     if key == "fixed":
         self.__mustCompute = False
         assert len(val) == 3, LOGGER.error(
             "fixed center must have exactly 3 elements corresponding to X,Y and Z coordinates of the center point."
         )
         val = np.array([FLOAT_TYPE(v) for v in val], dtype=FLOAT_TYPE)
     elif key == "indexes":
         self.__mustCompute = True
         for v in val:
             assert is_integer(v), LOGGER.error(
                 "indexes center items be integers")
         val = np.array([INT_TYPE(v) for v in val], dtype=INT_TYPE)
         for v in val:
             assert v >= 0, LOGGER.error(
                 "indexes center items be positive integers")
     else:
         self.__mustCompute = None
         raise Exception(
             LOGGER.error("center key must be either 'fixed' or 'indexes'"))
     # set center
     self.__center = {key: val}
Esempio n. 18
0
    def set_accepted(self, value):
        """
        Set constraint's number of accepted moves.

        :Parameters:
            #. value (integer): Constraint's number of accepted moves.
        """
        try:
            value = float(value)
        except:
            raise Exception(
                LOGGER.error("accepted value must be convertible to a number"))
        assert is_integer(value), LOGGER.error(
            "accepted value must be integer")
        assert value >= 0, LOGGER.error("accepted value must be positive")
        assert value <= self.__tried, LOGGER.error(
            "accepted value can't be bigger than number of tried moves")
        self.__accepted = int(value)
Esempio n. 19
0
    def set_atoms_list(self, atomsList):
        """
        Set atoms index list from which atoms will be picked to attempt removal.
        This method must be overloaded and not be called from this class but
        from its children. Otherwise a usage error will be raised.

        :Parameters:
            #. atomsList (None, list,set,tuple,np.ndarray): The list of atoms
               index to chose and remove from.
        """
        if atomsList is not None:
            C = _Container()
            # add container
            if not C.is_container('removeAtomsList'):
                C.add_container('removeAtomsList')
            # check if atomsList already defined
            loc = C.get_location_by_hint(atomsList)
            if loc is not None:
                atomsList = C.get_value(loc)
            else:
                assert isinstance(
                    atomsList, (list, tuple, np.ndarray)), LOGGER.error(
                        "atomsList must be either a list or a numpy.array")
                CL = []
                for idx in atomsList:
                    assert is_integer(idx), LOGGER.error(
                        "atomsList items must be integers")
                    assert idx >= 0, LOGGER.error(
                        "atomsList item must equal or bigger than 0")
                    CL.append(INT_TYPE(idx))
                setCL = set(CL)
                assert len(setCL) == len(CL), LOGGER.error(
                    "atomsList redundancy is not allowed")
                AL = np.array(CL, dtype=INT_TYPE)
                # add swapList to container
                C.set_value(container='removeAtomsList',
                            value=AL,
                            hint=atomsList)
                atomsList = AL
        # set atomsList attribute
        self.__atomsList = atomsList
        # reset collector state
        self._collectorState = None
Esempio n. 20
0
 def set_group_axis(self, groupAxis):
     """
     Sets group axis value.
     
     :Parameters:
        #. groupAxis (dict): The group axis. Only one key is allowed.
           If key is fixed, value must be a list, tuple or a numpy.array of a vector such as [X,Y,Z]
           If key is symmetry, in this case the group axis is computed as one of the three 
           symmetry axis of the group atoms. the value must be even 0, 1 or 2 for respectively 
           the first, second and tertiary symmetry axis.
     """
     assert isinstance(groupAxis, dict), LOGGER.error("groupAxis must be a dictionary")
     assert len(groupAxis) == 1, LOGGER.error("groupAxis must have a single key")       
     key = groupAxis.keys()[0]
     val = groupAxis[key]
     if key == "fixed":
         self.__mustComputeGroupAxis = False
         assert isinstance(val, (list,set,tuple,np.ndarray)), LOGGER.error("groupAxis value must be a list")
         if isinstance(val, np.ndarray):
             assert len(val.shape) == 1, LOGGER.error("groupAxis value must have a single dimension")
         val = list(val)
         assert len(val)==3, LOGGER.error("groupAxis fixed value must be a vector")
         for v in val:
             assert is_number(v), LOGGER.error("groupAxis value item must be numbers") 
         val  = np.array([FLOAT_TYPE(v) for v in val], dtype=FLOAT_TYPE)  
         norm = FLOAT_TYPE(np.sqrt(np.sum(val**2)))    
         val /= norm              
     elif key == "symmetry":
         self.__mustComputeGroupAxis = True
         assert is_integer(val), LOGGER.error("groupAxis symmetry value must be an integer") 
         val = INT_TYPE(val)
         assert val>=0 and val<3, LOGGER.error("groupAxis symmetry value must be positive smaller than 3") 
     else:
         self.__mustComputeGroupAxis = None
         raise Exception(LOGGER.error("groupAxis key must be either 'fixed' or 'symmetry'"))        
     # set groupAxis
     self.__groupAxis = {key:val}
Esempio n. 21
0
 def set_angles(self, anglesMap):
     """ 
     Sets the angles dictionary by parsing the anglesMap list.
     
     :Parameters:
         #. anglesMap (list): The angles map definition.
            Every item must be a list of five items.
            
            #. First item: The central atom index.
            #. Second item: The index of the left atom forming the angle (interchangeable with the right atom).
            #. Third item: The index of the right atom forming the angle (interchangeable with the left atom).
            #. Fourth item: The minimum lower limit or the minimum angle allowed in rad.
            #. Fifth item: The maximum upper limit or the maximum angle allowed in rad.
     """
     map = []
     if self.engine is not None:
         if anglesMap is not None:
             assert isinstance(anglesMap, (list, set, tuple)), LOGGER.error("anglesMap must be None or a list")
             for angle in anglesMap:
                 assert isinstance(angle, (list, set, tuple)), LOGGER.error("anglesMap items must be lists")
                 angle = list(angle)
                 assert len(angle)==5, LOGGER.error("anglesMap items must be lists of 5 items each")
                 centralIdx, leftIdx, rightIdx, lower, upper = angle
                 assert is_integer(centralIdx), LOGGER.error("anglesMap items lists of first item must be an integer")
                 centralIdx = INT_TYPE(centralIdx)
                 assert is_integer(leftIdx), LOGGER.error("anglesMap items lists of second item must be an integer")
                 leftIdx = INT_TYPE(leftIdx)
                 assert is_integer(rightIdx), LOGGER.error("anglesMap items lists of third item must be an integer")
                 rightIdx = INT_TYPE(rightIdx)
                 assert centralIdx>=0, LOGGER.error("anglesMap items lists first item must be positive")
                 assert leftIdx>=0, LOGGER.error("anglesMap items lists second item must be positive")
                 assert rightIdx>=0, LOGGER.error("anglesMap items lists third item must be positive")
                 assert centralIdx!=leftIdx, LOGGER.error("bondsMap items lists first and second items can't be the same")
                 assert centralIdx!=rightIdx, LOGGER.error("bondsMap items lists first and third items can't be the same")
                 assert leftIdx!=rightIdx, LOGGER.error("bondsMap items lists second and third items can't be the same")
                 assert is_number(lower), LOGGER.error("anglesMap items lists of third item must be a number")
                 lower = FLOAT_TYPE(lower)
                 assert is_number(upper), LOGGER.error("anglesMap items lists of fourth item must be a number")
                 upper = FLOAT_TYPE(upper)
                 assert lower>=0, LOGGER.error("anglesMap items lists fourth item must be positive")
                 assert upper>lower, LOGGER.error("anglesMap items lists fourth item must be smaller than the fifth item")
                 assert upper<=PI, LOGGER.error("anglesMap items lists fifth item must be smaller or equal to %.10f"%PI)
                 map.append((centralIdx, leftIdx, rightIdx, lower, upper))  
     # set anglesMap definition
     self.__anglesMap = map     
     # create bonds list of indexes arrays
     self.__angles = {}
     self.__atomsLUAD = {}
     if self.engine is not None:
         # parse bondsMap
         for angle in self.__anglesMap:
             centralIdx, leftIdx, rightIdx, lower, upper = angle
             assert centralIdx<len(self.engine.pdb), LOGGER.error("angle atom index must be smaller than maximum number of atoms")
             assert leftIdx<len(self.engine.pdb), LOGGER.error("angle atom index must be smaller than maximum number of atoms")
             assert rightIdx<len(self.engine.pdb), LOGGER.error("angle atom index must be smaller than maximum number of atoms")
             # create atoms look up angles dictionary
             if not self.__atomsLUAD.has_key(centralIdx):
                 self.__atomsLUAD[centralIdx] = []
             if not self.__atomsLUAD.has_key(leftIdx):
                 self.__atomsLUAD[leftIdx] = []
             if not self.__atomsLUAD.has_key(rightIdx):
                 self.__atomsLUAD[rightIdx] = []
             # create angles
             if not self.__angles.has_key(centralIdx):
                 self.__angles[centralIdx] = {"leftIndexes":[],"rightIndexes":[],"lower":[],"upper":[]}
             # check for redundancy and append
             elif leftIdx in self.__angles[centralIdx]["leftIndexes"]:
                 index = self.__angles[centralIdx]["leftIndexes"].index(leftIdx)
                 if rightIdx == self.__angles[centralIdx]["rightIndexes"][index]:
                     LOGGER.warn("Angle definition for central atom index '%i' and interchangeable left an right '%i' and '%i' is  already defined. New angle limits [%.3f,%.3f] ignored and old angle limits [%.3f,%.3f] kept."%(centralIdx, leftIdx, rightIdx, lower, upper, self.__angles[centralIdx]["lower"][index], self.__angles[centralIdx]["upper"][index]))
                     continue
             elif leftIdx in self.__angles[centralIdx]["rightIndexes"]:
                 index = self.__angles[centralIdx]["rightIndexes"].index(leftIdx)
                 if rightIdx == self.__angles[centralIdx]["leftIndexes"][index]:
                     LOGGER.warn("Angle definition for central atom index '%i' and interchangeable left an right '%i' and '%i' is  already defined. New angle limits [%.3f,%.3f] ignored and old angle limits [%.3f,%.3f] kept."%(centralIdx, leftIdx, rightIdx, lower, upper, self.__angles[centralIdx]["lower"][index], self.__angles[centralIdx]["upper"][index]))
                     continue
             # add angle definition
             self.__angles[centralIdx]["leftIndexes"].append(leftIdx)
             self.__angles[centralIdx]["rightIndexes"].append(rightIdx)
             self.__angles[centralIdx]["lower"].append(lower)
             self.__angles[centralIdx]["upper"].append(upper)
             self.__atomsLUAD[centralIdx].append(centralIdx)
             self.__atomsLUAD[leftIdx].append(centralIdx)
             self.__atomsLUAD[rightIdx].append(centralIdx)
         # finalize angles
         for idx in self.engine.pdb.xindexes:
             angles = self.__angles.get(idx, {"leftIndexes":[],"rightIndexes":[],"lower":[],"upper":[]} )
             self.__angles[INT_TYPE(idx)] =  {"leftIndexes": np.array(angles["leftIndexes"], dtype = INT_TYPE), 
                                              "rightIndexes": np.array(angles["rightIndexes"], dtype = INT_TYPE),
                                              "lower"  : np.array(angles["lower"]  , dtype = FLOAT_TYPE),
                                              "upper"  : np.array(angles["upper"]  , dtype = FLOAT_TYPE) }
             lut = self.__atomsLUAD.get(idx, [] )
             self.__atomsLUAD[INT_TYPE(idx)] = sorted(set(lut))
     # reset constraint
     self.__initialize_constraint__()
Esempio n. 22
0
    def add_bond(self, bond):
        """
        Add a single bond to constraint's list of bonds.

        :Parameters:
            #. bond (list): The bond list of four items.\n
               #. First atom index forming the bond.
               #. Second atom index forming the bond.
               #. Lower limit or the minimum bond length allowed.
               #. Upper limit or the maximum bond length allowed.
        """
        assert self.engine is not None, LOGGER.error(
            "setting a bond is not allowed unless engine is defined.")
        NUMBER_OF_ATOMS = self.engine.get_original_data("numberOfAtoms")
        assert isinstance(
            bond, (list, set, tuple)), LOGGER.error("bond items must be lists")
        assert len(bond) == 4, LOGGER.error(
            "bond items must be lists of 4 items each")
        idx1, idx2, lower, upper = bond
        assert is_integer(idx1), LOGGER.error(
            "bondsList items lists first item must be an integer")
        idx1 = INT_TYPE(idx1)
        assert is_integer(idx2), LOGGER.error(
            "bondsList items lists second item must be an integer")
        idx2 = INT_TYPE(idx2)
        assert idx1 < NUMBER_OF_ATOMS, LOGGER.error(
            "bond atom index must be smaller than maximum number of atoms")
        assert idx2 < NUMBER_OF_ATOMS, LOGGER.error(
            "bond atom index must be smaller than maximum number of atoms")
        assert idx1 >= 0, LOGGER.error("bond first item must be positive")
        assert idx2 >= 0, LOGGER.error("bond second item must be positive")
        assert idx1 != idx2, LOGGER.error(
            "bond first and second items can't be the same")
        assert is_number(lower), LOGGER.error(
            "bond third item must be a number")
        lower = FLOAT_TYPE(lower)
        assert is_number(upper), LOGGER.error(
            "bond fourth item must be a number")
        upper = FLOAT_TYPE(upper)
        assert lower >= 0, LOGGER.error("bond third item must be positive")
        assert upper > lower, LOGGER.error(
            "bond third item must be smaller than the fourth item")
        # create bonds
        if not self.__bonds.has_key(idx1):
            bondsIdx1 = {"indexes": [], "map": []}
        else:
            bondsIdx1 = {
                "indexes": self.__bonds[idx1]["indexes"],
                "map": self.__bonds[idx1]["map"]
            }
        if not self.__bonds.has_key(INT_TYPE(idx2)):
            bondsIdx2 = {"indexes": [], "map": []}
        else:
            bondsIdx2 = {
                "indexes": self.__bonds[idx2]["indexes"],
                "map": self.__bonds[idx2]["map"]
            }
        # set bond
        if idx2 in bondsIdx1["indexes"]:
            assert idx1 in bondsIdx2["indexes"], LOOGER.error(
                "mismatched bonds between atom '%s' and '%s'" % (idx1, idx2))
            at2InAt1 = bondsIdx1["indexes"].index(idx2)
            at1InAt2 = bondsIdx2["indexes"].index(idx1)
            assert bondsIdx1["map"][at2InAt1] == bondsIdx2["map"][
                at1InAt2], LOOGER.error(
                    "bonded atoms '%s' and '%s' point to different defintions"
                    % (idx1, idx2))
            setPos = bondsIdx1["map"][at2InAt1]
            LOGGER.warn(
                "Bond between atom index '%i' and '%i' is already defined. New bond limits [%.3f,%.3f] will replace old bond limits [%.3f,%.3f]. "
                % (idx2, idx1, lower, upper, self.__bondsList[2][setPos],
                   self.__bondsList[3][setPos]))
            self.__bondsList[0][setPos] = idx1
            self.__bondsList[1][setPos] = idx2
            self.__bondsList[2][setPos] = lower
            self.__bondsList[3][setPos] = upper
        else:
            bondsIdx1["map"].append(len(self.__bondsList[0]))
            bondsIdx2["map"].append(len(self.__bondsList[0]))
            bondsIdx1["indexes"].append(idx2)
            bondsIdx2["indexes"].append(idx1)
            self.__bondsList[0] = np.append(self.__bondsList[0], idx1)
            self.__bondsList[1] = np.append(self.__bondsList[1], idx2)
            self.__bondsList[2] = np.append(self.__bondsList[2], lower)
            self.__bondsList[3] = np.append(self.__bondsList[3], upper)
        self.__bonds[idx1] = bondsIdx1
        self.__bonds[idx2] = bondsIdx2
        # dump to repository
        if self.__dumpBonds:
            self._dump_to_repository({
                '_BondConstraint__bondsList': self.__bondsList,
                '_BondConstraint__bonds': self.__bonds
            })
            # reset constraint
            self.reset_constraint()
Esempio n. 23
0
 def set_bonds(self, bondsMap):
     """ 
     Sets the bonds dictionary by parsing the bondsMap list.
     
     :Parameters:
         #. bondsMap (list): The bonds map definition.
            Every item must be a list of four items.\n
            #. First item is the first atom index.
            #. Second item the second atom index forming the bond, 
            #. Third item: The lower limit or the minimum bond length allowed.
            #. Fourth item: The upper limit or the maximum bond length allowed.
     """
     map = []
     if self.engine is not None:
         if bondsMap is not None:
             assert isinstance(bondsMap, (list, set, tuple)), LOGGER.error("bondsMap must be None or a list")
             for bond in bondsMap:
                 assert isinstance(bond, (list, set, tuple)), LOGGER.error("bondsMap items must be lists")
                 bond = list(bond)
                 assert len(bond)==4, LOGGER.error("bondsMap items must be lists of 4 items each")
                 idx1, idx2, lower, upper = bond
                 assert is_integer(idx1), LOGGER.error("bondsMap items lists first item must be an integer")
                 idx1 = INT_TYPE(idx1)
                 assert is_integer(idx2), LOGGER.error("bondsMap items lists second item must be an integer")
                 idx2 = INT_TYPE(idx2)
                 assert idx1>=0, LOGGER.error("bondsMap items lists first item must be positive")
                 assert idx2>=0, LOGGER.error("bondsMap items lists second item must be positive")
                 assert idx1!=idx2, LOGGER.error("bondsMap items lists first and second items can't be the same")
                 assert is_number(lower), LOGGER.error("bondsMap items lists of third item must be a number")
                 lower = FLOAT_TYPE(lower)
                 assert is_number(upper), LOGGER.error("bondsMap items lists of fourth item must be a number")
                 upper = FLOAT_TYPE(upper)
                 assert lower>=0, LOGGER.error("bondsMap items lists third item must be positive")
                 assert upper>lower, LOGGER.error("bondsMap items lists third item must be smaller than the fourth item")
                 map.append((idx1, idx2, lower, upper))  
     # set bondsMap definition
     self.__bondsMap = map      
     # create bonds list of indexes arrays
     self.__bonds = {}
     if self.engine is not None:
         # parse bondsMap
         for bond in self.__bondsMap:
             idx1, idx2, lower, upper = bond
             assert idx1<len(self.engine.pdb), LOGGER.error("bond atom index must be smaller than maximum number of atoms")
             assert idx2<len(self.engine.pdb), LOGGER.error("bond atom index must be smaller than maximum number of atoms")
             # create bonds
             if not self.__bonds.has_key(idx1):
                 self.__bonds[idx1] = {"indexes":[],"lower":[],"upper":[]}
             if not self.__bonds.has_key(idx2):
                 self.__bonds[idx2] = {"indexes":[],"lower":[],"upper":[]}
             # check for redundancy and append
             if idx2 in self.__bonds[idx1]["indexes"]:
                 index = self.__bonds[idx1]["indexes"].index(idx2)
                 log.LocalLogger("fullrmc").logger.warn("Atom index '%i' is already defined in atom '%i' bonds list. New bond limits [%.3f,%.3f] ignored and old bond limits [%.3f,%.3f] kept. "%(idx2, idx1, lower, upper, self.__bonds[idx1]["lower"][indexes], self.__bonds[idx1]["upper"][indexes]))
             else:
                 self.__bonds[idx1]["indexes"].append(idx2)
                 self.__bonds[idx1]["lower"].append(lower)
                 self.__bonds[idx1]["upper"].append(upper)
             if idx1 in self.__bonds[idx2]["indexes"]:
                 index = self.__bonds[idx2]["indexes"].index(idx1)
                 log.LocalLogger("fullrmc").logger.warn("Atom index '%i' is already defined in atom '%i' bonds list. New bond limits [%.3f,%.3f] ignored and old bond limits [%.3f,%.3f] kept. "%(idx1, idx2, lower, upper, self.__bonds[idx2]["lower"][indexes], self.__bonds[idx1]["upper"][indexes]))
             else:
                 self.__bonds[idx2]["indexes"].append(idx1)
                 self.__bonds[idx2]["lower"].append(lower)
                 self.__bonds[idx2]["upper"].append(upper)
         # finalize bonds
         for idx in self.engine.pdb.xindexes:
             bonds = self.__bonds.get(idx, {"indexes":[],"lower":[],"upper":[]} )
             self.__bonds[INT_TYPE(idx)] =  {"indexes": np.array(bonds["indexes"], dtype = INT_TYPE)  ,
                                             "lower"  : np.array(bonds["lower"]  , dtype = FLOAT_TYPE),
                                             "upper"  : np.array(bonds["upper"]  , dtype = FLOAT_TYPE) }
     # reset constraint
     self.__initialize_constraint__()
Esempio n. 24
0
    def set_orientation_axis(self, orientationAxis):
        """
        Set orientation axis value.

        :Parameters:
            #. orientationAxis (dict): The axis to align the group axis with.
               If key is fixed, value must be a list, tuple or a numpy.array
               of a vector such as [X,Y,Z]. If Key is symmetry, in this case
               the value must be a list of two items, the first one is a list
               of atoms indexes to compute symmetry axis and the second item
               must be even 0, 1 or 2 for respectively the first, second and
               tertiary symmetry axis.
        """
        assert isinstance(
            orientationAxis,
            dict), LOGGER.error("orientationAxis must be a dictionary")
        assert len(orientationAxis) == 1, LOGGER.error(
            "orientationAxis must have a single key")
        key = orientationAxis.keys()[0]
        val = orientationAxis[key]
        if key == "fixed":
            self.__mustComputeOrientationAxis = False
            assert isinstance(val,
                              (list, set, tuple, np.ndarray)), LOGGER.error(
                                  "orientationAxis value must be a list")
            if isinstance(val, np.ndarray):
                assert len(val.shape) == 1, LOGGER.error(
                    "orientationAxis value must have a single dimension")
            val = list(val)
            assert len(val) == 3, LOGGER.error(
                "orientationAxis fixed value must be a vector")
            for v in val:
                assert is_number(v), LOGGER.error(
                    "orientationAxis value item must be numbers")
            val = np.array([FLOAT_TYPE(v) for v in val], dtype=FLOAT_TYPE)
            norm = FLOAT_TYPE(np.sqrt(np.sum(val**2)))
            val /= norm
        elif key == "symmetry":
            self.__mustComputeOrientationAxis = True
            assert isintance(val, (list, tuple)), LOGGER.error(
                "orientationAxis symmetry value must be a list")
            assert len(val) == 2, LOGGER.error(
                "orientationAxis symmetry value must be a list of two items")
            val0 = []
            for v in val[0]:
                assert is_integer(v), LOGGER.error(
                    "orientationAxis symmetry value list items must be integers"
                )
                v0 = INT_TYPE(v)
                assert v0 >= 0, LOGGER.error(
                    "orientationAxis symmetry value list items must be positive"
                )
                val0.append(v0)
            assert len(set(val0)) == len(val[0]), LOGGER.error(
                "orientationAxis symmetry value list redundant items indexes found"
            )
            val0 = np.array(val0, dtype=INT_TYPE)
            val1 = val[1]
            assert is_integer(val1), LOGGER.error(
                "orientationAxis symmetry value second item must be an integer"
            )
            val1 = INT_TYPE(val1)
            assert val1 >= 0 and val1 < 3, LOGGER.error(
                "orientationAxis symmetry value second item must be positive smaller than 3"
            )
            val = (val0, val1)
        else:
            self.__mustComputeOrientationAxis = None
            raise Exception(
                LOGGER.error(
                    "orientationAxis key must be either 'fixed' or 'symmetry'")
            )
        # set orientationAxis
        self.__orientationAxis = {key: val}
 def set_angles(self, anglesMap):
     """ 
     Sets the angles dictionary by parsing the anglesMap list.
     
     :Parameters:
         #. anglesMap (list): The angles map definition.
            Every item must be a list of five items.\n
            #. First item: The improper atom index that must be in the plane.
            #. Second item: The index of the atom 'O' considered the origin of the plane.
            #. Third item: The index of the atom 'x' used to calculated 'Ox' vector.
            #. Fourth item: The index of the atom 'y' used to calculated 'Oy' vector.
            #. Fifth item: The minimum lower limit or the minimum angle allowed in rad.
            #. Sixth item: The maximum upper limit or the maximum angle allowed in rad.
     """
     map = []
     if self.engine is not None:
         if anglesMap is not None:
             assert isinstance(anglesMap, (list, set, tuple)), LOGGER.error("anglesMap must be None or a list")
             for angle in anglesMap:
                 assert isinstance(angle, (list, set, tuple)), LOGGER.error("anglesMap items must be lists")
                 angle = list(angle)
                 assert len(angle)==6, LOGGER.error("anglesMap items must be lists of 6 items each")
                 improperIdx, oIdx, xIdx, yIdx, lower, upper = angle
                 assert is_integer(improperIdx), LOGGER.error("anglesMap items lists of first item must be an integer")
                 improperIdx = INT_TYPE(improperIdx)
                 assert is_integer(oIdx), LOGGER.error("anglesMap items lists of second item must be an integer")
                 oIdx = INT_TYPE(oIdx)
                 assert is_integer(xIdx), LOGGER.error("anglesMap items lists of third item must be an integer")
                 xIdx = INT_TYPE(xIdx)
                 assert is_integer(yIdx), LOGGER.error("anglesMap items lists of fourth item must be an integer")
                 yIdx = INT_TYPE(yIdx)
                 assert improperIdx>=0, LOGGER.error("anglesMap items lists first item must be positive")
                 assert oIdx>=0, LOGGER.error("anglesMap items lists second item must be positive")
                 assert xIdx>=0, LOGGER.error("anglesMap items lists third item must be positive")
                 assert yIdx>=0, LOGGER.error("anglesMap items lists fourth item must be positive")
                 assert improperIdx!=oIdx, LOGGER.error("bondsMap items lists first and second items can't be the same")
                 assert improperIdx!=xIdx, LOGGER.error("bondsMap items lists first and third items can't be the same")
                 assert improperIdx!=yIdx, LOGGER.error("bondsMap items lists first and fourth items can't be the same")
                 assert oIdx!=xIdx, LOGGER.error("bondsMap items lists second and third items can't be the same")
                 assert oIdx!=yIdx, LOGGER.error("bondsMap items lists second and fourth items can't be the same")
                 assert xIdx!=yIdx, LOGGER.error("bondsMap items lists third and fourth items can't be the same")
                 assert is_number(lower), LOGGER.error("anglesMap items lists of fifth item must be a number")
                 lower = FLOAT_TYPE(lower)
                 assert is_number(upper), LOGGER.error("anglesMap items lists of sixth item must be a number")
                 upper = FLOAT_TYPE(upper)
                 assert lower>=FLOAT_TYPE(-PI/2), LOGGER.error("anglesMap items lists fifth item must be bigger than %10f"%FLOAT_TYPE(-PI/2))
                 assert upper>lower, LOGGER.error("anglesMap items lists fifth item must be smaller than the sixth item")
                 assert upper<=FLOAT_TYPE(PI/2), LOGGER.error("anglesMap items lists fifth item must be smaller or equal to %.10f"%FLOAT_TYPE(PI/2))
                 map.append((improperIdx, oIdx, xIdx, yIdx, lower, upper))  
     # set anglesMap definition
     self.__anglesMap = map      
     # create bonds list of indexes arrays
     self.__angles = {}
     self.__atomsLUAD = {}
     if self.engine is not None:
         # parse bondsMap
         for angle in self.__anglesMap:
             improperIdx, oIdx, xIdx, yIdx, lower, upper = angle
             assert improperIdx<len(self.engine.pdb), LOGGER.error("angle atom index must be smaller than maximum number of atoms")
             assert oIdx<len(self.engine.pdb), LOGGER.error("angle atom index must be smaller than maximum number of atoms")
             assert xIdx<len(self.engine.pdb), LOGGER.error("angle atom index must be smaller than maximum number of atoms")
             assert yIdx<len(self.engine.pdb), LOGGER.error("angle atom index must be smaller than maximum number of atoms")
             # create atoms look up angles dictionary
             if not self.__atomsLUAD.has_key(improperIdx):
                 self.__atomsLUAD[improperIdx] = []
             if not self.__atomsLUAD.has_key(oIdx):
                 self.__atomsLUAD[oIdx] = []
             if not self.__atomsLUAD.has_key(xIdx):
                 self.__atomsLUAD[xIdx] = []
             if not self.__atomsLUAD.has_key(yIdx):
                 self.__atomsLUAD[yIdx] = []
             # create improper angles
             if not self.__angles.has_key(improperIdx):
                 self.__angles[improperIdx] = {"oIndexes":[],"xIndexes":[],"yIndexes":[],"lower":[],"upper":[]}
             # check for redundancy and append
             elif oIdx in self.__angles[improperIdx]["oIndexes"]:
                 index = self.__angles[improperIdx]["oIndexes"].index(oIndexes)
                 if sorted(oIdx,xIdx,yIdx) == sorted(self.__angles[improperIdx]["oIndexes"][index],self.__angles[improperIdx]["xIndexes"][index],self.__angles[improperIdx]["yIndexes"][index]):
                     log.LocalLogger("fullrmc").logger.warn("Improper angle definition for improper atom index '%i' and (O,x,y) atoms indexes (%i,%i,%i)  already defined. New angle limits [%.3f,%.3f] ignored and old angle limits [%.3f,%.3f] kept."%(improperIdx, oIdx, xIdx, yIdx, lower, upper, self.__angles[improperIdx]["lower"][index], self.__angles[improperIdx]["upper"][index]))
                     continue
             # add improper angle definition
             self.__angles[improperIdx]["oIndexes"].append(oIdx)
             self.__angles[improperIdx]["xIndexes"].append(xIdx)
             self.__angles[improperIdx]["yIndexes"].append(yIdx)
             self.__angles[improperIdx]["lower"].append(lower)
             self.__angles[improperIdx]["upper"].append(upper)
             self.__atomsLUAD[improperIdx].append(improperIdx)
             self.__atomsLUAD[oIdx].append(improperIdx)
             self.__atomsLUAD[xIdx].append(improperIdx)
             self.__atomsLUAD[yIdx].append(improperIdx)
         # finalize improper angles
         for idx in self.engine.pdb.xindexes:
             angles = self.__angles.get(idx, {"oIndexes":[],"xIndexes":[],"yIndexes":[],"lower":[],"upper":[]} )
             self.__angles[INT_TYPE(idx)] =  {"oIndexes": np.array(angles["oIndexes"], dtype = INT_TYPE), 
                                              "xIndexes": np.array(angles["xIndexes"], dtype = INT_TYPE),
                                              "yIndexes": np.array(angles["yIndexes"], dtype = INT_TYPE),
                                              "lower"  : np.array(angles["lower"]  , dtype = FLOAT_TYPE),
                                              "upper"  : np.array(angles["upper"]  , dtype = FLOAT_TYPE) }
             lut = self.__atomsLUAD.get(idx, [] )
             self.__atomsLUAD[INT_TYPE(idx)] = sorted(set(lut))
     # reset constraint
     self.__initialize_constraint__()
Esempio n. 26
0
    def set_coordination_number_definition(self, coordNumDef):
        """
        Set the coordination number definition.

        :Parameters:
            #. coordNumDef (None, list, tuple): Coordination number definition.
               It must be None, list or tuple where every element is a list or
               a tuple of exactly 6 items and an optional 7th item for weight.

               #. core atoms: Can be any of the following:

                  * string: indicating atomic element.
                  * dictionary: Key as atomic attribute among (element, name)
                    and value is the attribute value.
                  * list, tuple, set, numpy.ndarray: core atoms index.

               #. in shell atoms: Can be any of the following:

                  * string: indicating atomic element.
                  * dictionary: Key as atomic attribute among (element, name)
                    and value is the attribute value.
                  * list, tuple, set, numpy.ndarray: in shell atoms index

               #. Lower distance limit of the coordination shell.
               #. Upper distance limit of the coordination shell.
               #. :math:`N_{min}` : minimum number of neighbours in the
                  shell.
               #. :math:`N_{max}` : maximum number of neighbours in the
                  shell.
               #. :math:`W_{i}` : weight contribution to the standard error,
                  this is optional, if not given it is set automatically to 1.0.

               ::

                   e.g. [ ('Ti','Ti', 2.5, 3.5, 5, 7.1, 1), ('Ni','Ti', 2.2, 3.1, 7.2, 9.7, 100), ...]
                        [ ({'element':'Ti'},'Ti', 2.5, 3.5, 5, 7.1, 0.1), ...]
                        [ ({'name':'au'},'Au', 2.5, 3.5, 4.1, 6.3), ...]
                        [ ({'name':'Ni'},{'element':'Ti'}, 2.2, 3.1, 7, 9), ...]
                        [ ('Ti',range(100,500), 2.2, 3.1, 7, 9), ...]
                        [ ([0,10,11,15,1000],{'name':'Ti'}, 2.2, 3.1, 7, 9, 5), ...]

        """
        if self.engine is None:
            self.__coordNumDef = coordNumDef
            return
        elif coordNumDef is None:
            coordNumDef = []
        ########## check definitions, create coordination number data ##########
        self.__initialize_constraint_data()
        ALL_NAMES = self.engine.get_original_data("allNames")
        NAMES = self.engine.get_original_data("names")
        ALL_ELEMENTS = self.engine.get_original_data("allElements")
        ELEMENTS = self.engine.get_original_data("elements")
        NUMBER_OF_ATOMS = self.engine.get_original_data("numberOfAtoms")
        for CNDef in coordNumDef:
            assert isinstance(CNDef, (list, tuple)), LOGGER.error(
                "coordNumDef item must be a list or a tuple")
            if len(CNDef) == 6:
                coreDef, shellDef, lowerShell, upperShell, minCN, maxCN = CNDef
                weight = 1.0
            elif len(CNDef) == 7:
                coreDef, shellDef, lowerShell, upperShell, minCN, maxCN, weight = CNDef
            else:
                raise LOGGER.error("coordNumDef item must have 6 or 7 items")
            # core definition
            if isinstance(coreDef, basestring):
                coreDef = str(coreDef)
                assert coreDef in ELEMENTS, LOGGER.error(
                    "core atom definition '%s' is not a valid element" %
                    coreDef)
                coreIndexes = [
                    idx for idx, el in enumerate(ALL_ELEMENTS) if el == coreDef
                ]
            elif isinstance(coreDef, dict):
                assert len(coreDef) == 1, LOGGER.error(
                    "core atom definition dictionary must be of length 1")
                key, value = coreDef.keys()[0], coreDef.values()[0]
                if key is "name":
                    assert value in NAMES, LOGGER.error(
                        "core atom definition '%s' is not a valid name" %
                        coreDef)
                    coreIndexes = [
                        idx for idx, el in enumerate(ALL_NAMES)
                        if el == coreDef
                    ]
                elif key is "element":
                    assert value in ELEMENTS, LOGGER.error(
                        "core atom definition '%s' is not a valid element" %
                        coreDef)
                    coreIndexes = [
                        idx for idx, el in enumerate(ALL_ELEMENTS)
                        if el == coreDef
                    ]
                else:
                    raise LOGGER.error(
                        "core atom definition dictionary key must be either 'name' or 'element'"
                    )
            elif isinstance(coreDef, (list, tuple, set, np.ndarray)):
                coreIndexes = []
                if isinstance(coreDef, np.ndarray):
                    assert len(coreDef.shape) == 1, LOGGER.error(
                        "core atom definition numpy.ndarray must be 1D")
                for c in coreDef:
                    assert is_integer(c), LOGGER.error(
                        "core atom definition index must be integer")
                    c = INT_TYPE(c)
                    assert c >= 0, LOGGER.error(
                        "core atom definition index must be >=0")
                    assert c < NUMBER_OF_ATOMS, LOGGER.error(
                        "core atom definition index must be smaler than number of atoms in system"
                    )
                    coreIndexes.append(c)
            # shell definition
            if isinstance(shellDef, basestring):
                shellDef = str(shellDef)
                assert shellDef in ELEMENTS, LOGGER.error(
                    "core atom definition '%s' is not a valid element" %
                    shellDef)
                shellIndexes = [
                    idx for idx, el in enumerate(ALL_ELEMENTS)
                    if el == shellDef
                ]
            elif isinstance(shellDef, dict):
                assert len(shellDef) == 1, LOGGER.error(
                    "core atom definition dictionary must be of length 1")
                key, value = shellDef.keys()[0], shellDef.values()[0]
                if key is "name":
                    assert value in NAMES, LOGGER.error(
                        "core atom definition '%s' is not a valid name" %
                        shellDef)
                    shellIndexes = [
                        idx for idx, el in enumerate(ALL_NAMES)
                        if el == shellDef
                    ]
                elif key is "element":
                    assert value in ELEMENTS, LOGGER.error(
                        "core atom definition '%s' is not a valid element" %
                        shellDef)
                    shellIndexes = [
                        idx for idx, el in enumerate(ALL_ELEMENTS)
                        if el == shellDef
                    ]
                else:
                    raise LOGGER.error(
                        "core atom definition dictionary key must be either 'name' or 'element'"
                    )
            elif isinstance(shellDef, (list, tuple, set, np.ndarray)):
                shellIndexes = []
                if isinstance(shellDef, np.ndarray):
                    assert len(shellDef.shape) == 1, LOGGER.error(
                        "core atom definition numpy.ndarray must be 1D")
                for c in shellDef:
                    assert is_integer(c), LOGGER.error(
                        "core atom definition index must be integer")
                    c = INT_TYPE(c)
                    assert c >= 0, LOGGER.error(
                        "core atom definition index must be >=0")
                    assert c < NUMBER_OF_ATOMS, LOGGER.error(
                        "core atom definition index must be smaler than number of atoms in system"
                    )
                    shellIndexes.append(c)
            # lower and upper shells definition
            assert is_number(lowerShell), LOGGER.error(
                "Coordination number lower shell '%s' must be a number." %
                lowerShell)
            lowerShell = FLOAT_TYPE(lowerShell)
            assert lowerShell >= 0, LOGGER.error(
                "Coordination number lower shell '%s' must be a positive." %
                lowerShell)
            assert is_number(upperShell), LOGGER.error(
                "Coordination number upper shell '%s' must be a number." % key)
            upperShell = FLOAT_TYPE(upperShell)
            assert upperShell > lowerShell, LOGGER.error(
                "Coordination number lower shell '%s' must be smaller than upper shell %s"
                % (lowerShell, upperShell))
            # minimum and maximum number of atoms definitions
            assert is_number(minCN), LOGGER.error(
                "Coordination number minimum atoms '%s' must be a number." %
                minCN)
            minCN = FLOAT_TYPE(minCN)
            assert minCN >= 0, LOGGER.error(
                "Coordination number minimim atoms '%s' must be >=0." % minCN)
            assert is_number(maxCN), LOGGER.error(
                "Coordination number maximum atoms '%s' must be a number." %
                key)
            maxCN = FLOAT_TYPE(maxCN)
            assert maxCN >= minCN, LOGGER.error(
                "Coordination number minimum atoms '%s' must be smaller than maximum atoms %s"
                % (minCN, maxCN))
            # check weight
            assert is_number(weight), LOGGER.error(
                "Coordination number weight '%s' must be a number." % weight)
            weight = FLOAT_TYPE(weight)
            assert weight > 0, LOGGER.error(
                "Coordination number weight '%s' must be >0." % weight)
            # append coordination number data
            self.__coresIndexes.append(sorted(set(coreIndexes)))
            self.__shellsIndexes.append(sorted(set(shellIndexes)))
            self.__lowerShells.append(lowerShell)
            self.__upperShells.append(upperShell)
            self.__minAtoms.append(minCN)
            self.__maxAtoms.append(maxCN)
            #self.__coordNumData.append( FLOAT_TYPE(0) )
            self.__coordNumData.append(None)
            self.__weights.append(weight)
        ########## set asCoreDefIdxs and inShellDefIdxs points ##########
        for _ in xrange(NUMBER_OF_ATOMS):
            self.__asCoreDefIdxs.append([])
            self.__inShellDefIdxs.append([])
        for defIdx, indexes in enumerate(self.__coresIndexes):
            self.__coresIndexes[defIdx] = np.array(indexes, dtype=INT_TYPE)
            for atIdx in indexes:
                self.__asCoreDefIdxs[atIdx].append(defIdx)
        for defIdx, indexes in enumerate(self.__shellsIndexes):
            self.__shellsIndexes[defIdx] = np.array(indexes, dtype=INT_TYPE)
            for atIdx in indexes:
                self.__inShellDefIdxs[atIdx].append(defIdx)
        for atIdx in xrange(NUMBER_OF_ATOMS):
            self.__asCoreDefIdxs[atIdx] = np.array(self.__asCoreDefIdxs[atIdx],
                                                   dtype=INT_TYPE)
            self.__inShellDefIdxs[atIdx] = np.array(
                self.__inShellDefIdxs[atIdx], dtype=INT_TYPE)
        # set all to arrays
        #self.__coordNumData  = np.array( self.__coordNumData, dtype=FLOAT_TYPE )
        self.__weights = np.array(self.__weights, dtype=FLOAT_TYPE)
        self.__numberOfCores = np.array(
            [len(idxs) for idxs in self.__coresIndexes], dtype=FLOAT_TYPE)
        # set definition
        self.__coordNumDef = coordNumDef
        # dump to repository
        self._dump_to_repository({
            '_AtomicCoordinationNumberConstraint__coordNumDef':
            self.__coordNumDef,
            '_AtomicCoordinationNumberConstraint__coordNumData':
            self.__coordNumData,
            '_AtomicCoordinationNumberConstraint__weights':
            self.__weights,
            '_AtomicCoordinationNumberConstraint__numberOfCores':
            self.__numberOfCores,
            '_AtomicCoordinationNumberConstraint__coresIndexes':
            self.__coresIndexes,
            '_AtomicCoordinationNumberConstraint__shellsIndexes':
            self.__shellsIndexes,
            '_AtomicCoordinationNumberConstraint__lowerShells':
            self.__lowerShells,
            '_AtomicCoordinationNumberConstraint__upperShells':
            self.__upperShells,
            '_AtomicCoordinationNumberConstraint__minAtoms':
            self.__minAtoms,
            '_AtomicCoordinationNumberConstraint__maxAtoms':
            self.__maxAtoms
        })
        # reset constraint
        self.reset_constraint()  # ADDED 2017-JAN-08