parameters: (self, file_obj=None, data=None)
docstring: Reads vibrational modes (frequencies and atomic displacements).
          :param file_obj: file object from which we read
          :param data: Python dictionary to which k-point data should be added
docstring_summary: Reads vibrational modes (frequencies and atomic displacements).
          :param file_obj: file object from which we read
          :param data: Python dictionary to which k-point data should be added
docstring_tokens: Reads vibrational modes ( frequencies and atomic displacements ) . : param file_obj : file object from which we read : param data : Python dictionary to which k - point data should be added
function: def _read_modes(self, file_obj=None, data=None):
          """
          Reads vibrational modes (frequencies and atomic displacements).
          :param file_obj: file object from which we read
          :param data: Python dictionary to which k-point data should be added
          """
          end_msgs = ["STANDARD"]
          freq = []
          xdisp = []
          ydisp = []
          zdisp = []
  
          # parse block with frequencies and atomic displacements
          while not (self._parser.block_end(file_obj=file_obj, msg=end_msgs)
                     or self._parser.file_end(file_obj=file_obj)):
  
              self._read_freq_block(file_obj=file_obj, freq=freq)
              self._read_coord_block(file_obj=file_obj, xdisp=xdisp, ydisp=ydisp, zdisp=zdisp)
  
          freq = [freq]
          weights = [1.0]
          k_coordinates = [[0.0, 0.0, 0.0]]
          displacements = [[xdisp, ydisp, zdisp]]
  
          #  Non-periodic calculations may remove modes 1-6
          self._num_modes = len(freq[0])
          if self._num_modes == 3 * self._num_atoms:
              pass
          elif self._num_modes + 6 == 3 * self._num_atoms:
              pass
          else:
              raise ValueError("Invalid number of modes.")
  
          self._num_k = 1  # Only Gamma point
  
          data["frequencies"] = np.asarray(freq).astype(dtype=FLOAT_TYPE, casting="safe")
          data["k_vectors"] = np.asarray(k_coordinates).astype(dtype=FLOAT_TYPE, casting="safe")
          data["weights"] = np.asarray(weights).astype(dtype=FLOAT_TYPE, casting="safe")
  
          num_freq = len(freq[0])
          num_atoms = len(data["atoms"])
  
          # Reshape displacements so that Abins can use it to create its internal data objects
          # num_atoms: number of atoms in the system
          # num_freq: number of modes
          # dim: dimension for each atomic displacement (atoms vibrate in 3D space)
          #
          # The following conversion is necessary:
          # (num_freq * num_atom * dim) -> (num_freq, num_atom, dim) -> (num_atom, num_freq, dim)
          dim = 3
  
          # displacements[num_freq, num_atom, dim]
          displacements = np.reshape(a=np.asarray(a=displacements, order="C"), newshape=(num_freq, num_atoms, dim))
  
          # Normalise atomic displacements so that the sum of all atomic
          # displacements in any normal mode is normalised (equal 1).
          # num_freq, num_atom, dim -> num_freq, num_atom, dim, dim -> num_freq, num_atom -> num_freq
          displacements /= self._norm
          norm = np.sum(np.trace(np.einsum('lki, lkj->lkij', displacements, displacements.conjugate()),
                                 axis1=2, axis2=3), axis=1)
          displacements = np.einsum('ijk, i-> ijk', displacements, 1.0 / np.sqrt(norm))
  
          # displacements[num_atoms, num_freq, dim]
          displacements = np.transpose(a=displacements, axes=(1, 0, 2))
  
          # displacements[num_k, num_atoms, num_freq, dim]
          # with num_k = 1
          data["atomic_displacements"] = np.asarray([displacements])
function_tokens: def _read_modes ( self , file_obj = None , data = None ) : end_msgs = [ "STANDARD" ] freq = [ ] xdisp = [ ] ydisp = [ ] zdisp = [ ] # parse block with frequencies and atomic displacements while not ( self . _parser . block_end ( file_obj = file_obj , msg = end_msgs ) or self . _parser . file_end ( file_obj = file_obj ) ) : self . _read_freq_block ( file_obj = file_obj , freq = freq ) self . _read_coord_block ( file_obj = file_obj , xdisp = xdisp , ydisp = ydisp , zdisp = zdisp ) freq = [ freq ] weights = [ 1.0 ] k_coordinates = [ [ 0.0 , 0.0 , 0.0 ] ] displacements = [ [ xdisp , ydisp , zdisp ] ] #  Non-periodic calculations may remove modes 1-6 self . _num_modes = len ( freq [ 0 ] ) if self . _num_modes == 3 * self . _num_atoms : pass elif self . _num_modes + 6 == 3 * self . _num_atoms : pass else : raise ValueError ( "Invalid number of modes." ) self . _num_k = 1 # Only Gamma point data [ "frequencies" ] = np . asarray ( freq ) . astype ( dtype = FLOAT_TYPE , casting = "safe" ) data [ "k_vectors" ] = np . asarray ( k_coordinates ) . astype ( dtype = FLOAT_TYPE , casting = "safe" ) data [ "weights" ] = np . asarray ( weights ) . astype ( dtype = FLOAT_TYPE , casting = "safe" ) num_freq = len ( freq [ 0 ] ) num_atoms = len ( data [ "atoms" ] ) # Reshape displacements so that Abins can use it to create its internal data objects # num_atoms: number of atoms in the system # num_freq: number of modes # dim: dimension for each atomic displacement (atoms vibrate in 3D space) # # The following conversion is necessary: # (num_freq * num_atom * dim) -> (num_freq, num_atom, dim) -> (num_atom, num_freq, dim) dim = 3 # displacements[num_freq, num_atom, dim] displacements = np . reshape ( a = np . asarray ( a = displacements , order = "C" ) , newshape = ( num_freq , num_atoms , dim ) ) # Normalise atomic displacements so that the sum of all atomic # displacements in any normal mode is normalised (equal 1). # num_freq, num_atom, dim -> num_freq, num_atom, dim, dim -> num_freq, num_atom -> num_freq displacements /= self . _norm norm = np . sum ( np . trace ( np . einsum ( 'lki, lkj->lkij' , displacements , displacements . conjugate ( ) ) , axis1 = 2 , axis2 = 3 ) , axis = 1 ) displacements = np . einsum ( 'ijk, i-> ijk' , displacements , 1.0 / np . sqrt ( norm ) ) # displacements[num_atoms, num_freq, dim] displacements = np . transpose ( a = displacements , axes = ( 1 , 0 , 2 ) ) # displacements[num_k, num_atoms, num_freq, dim] # with num_k = 1 data [ "atomic_displacements" ] = np . asarray ( [ displacements ] )