@@ -162,6 +162,59 @@ def primitives(self, spherical):
162162 #self.gaussian = gaussian
163163
164164
165+ def deduplicate_basis_sets (sets , sp = False ):
166+ """Deduplicate identical basis sets on different centers.
167+
168+ Args:
169+ sets (pd.DataFrame): non-unique basis sets
170+ sp (bool): Whether or not to call _expand_sp (gaussian program only)
171+
172+ Returns:
173+ tup (tuple): deduplicated basis sets and basis set map for atom table
174+ """
175+ unique , setmap , cnt = [], {}, 0
176+ sets = sets .groupby ('center' )
177+ chk = ['alpha' , 'd' ]
178+ for center , seht in sets :
179+ for i , other in enumerate (unique ):
180+ if other .shape != seht .shape : continue
181+ if np .allclose (other [chk ], seht [chk ]):
182+ setmap [center ] = i
183+ break
184+ else :
185+ unique .append (seht )
186+ setmap [center ] = cnt
187+ cnt += 1
188+ if sp : unique = _expand_sp (unique )
189+ sets = pd .concat (unique ).reset_index (drop = True )
190+ try : sets .drop ([2 , 3 ], axis = 1 , inplace = True )
191+ except (KeyError , ValueError ): pass
192+ sets .rename (columns = {'center' : 'set' }, inplace = True )
193+ sets ['set' ] = sets ['set' ].map (setmap )
194+ sets ['frame' ] = 0
195+ return sets , setmap
196+
197+ def _expand_sp (unique ):
198+ """Currently only used when 'program' == 'gaussian'."""
199+ expand = []
200+ for seht in unique :
201+ if np .isnan (seht [2 ]).sum () == seht .shape [0 ]:
202+ expand .append (seht )
203+ continue
204+ sps = seht [2 ][~ np .isnan (seht [2 ])].index
205+ shls = len (seht .ix [sps ]['shell' ].unique ())
206+ dupl = seht .ix [sps [0 ]:sps [- 1 ]].copy ()
207+ dupl [1 ] = dupl [2 ]
208+ dupl ['L' ] = 1
209+ dupl ['shell' ] += shls
210+ last = seht .ix [sps [- 1 ] + 1 :].copy ()
211+ last ['shell' ] += shls
212+ expand .append (pd .concat ([seht .ix [:sps [0 ] - 1 ],
213+ seht .ix [sps [0 ]:sps [- 1 ]],
214+ dupl , last ]))
215+ return expand
216+
217+
165218class BasisSetOrder (DataFrame ):
166219 """
167220 BasisSetOrder uniquely determines the basis function ordering scheme for
@@ -223,22 +276,38 @@ class Overlap(DataFrame):
223276 _columns = ['chi0' , 'chi1' , 'coef' , 'frame' ]
224277 _index = 'index'
225278
226- #@property
227- #def _constructor(self):
228- # return Overlap
229279
230- def square (self , frame = 0 , column = 'coef' , mocoefs = None ):
280+ def square (self , frame = 0 , column = 'coef' , mocoefs = None , irrep = None ):
231281 """Return a 'square' matrix DataFrame of the Overlap.
232282
233283 Args:
234284 column (str): column of coefficients to reshape
235285 mocoefs (str): alias for `column`
236286 frame (int): default 0
287+ irrep (int): irreducible representation if symmetrized
237288 """
238289 if mocoefs is not None : column = mocoefs
290+ if 'irrep' in self .columns :
291+ if irrep is None :
292+ irreps , i , j = self .groupby ('irrep' ), 0 , 0
293+ norb = (irreps .chi0 .max () + 1 ).sum ()
294+ nchi = (irreps .chi1 .max () + 1 ).sum ()
295+ cmat = np .zeros ((nchi , norb ))
296+ for irrep , grp in irreps :
297+ piv = grp .pivot ('chi0' , 'chi1' , column )
298+ ii , jj = piv .shape
299+ cmat [i : i + ii , j : j + jj ] = piv .values
300+ i += ii
301+ j += jj
302+ idx = pd .Index (range (nchi ), name = 'chi0' )
303+ orb = pd .Index (range (norb ), name = 'chi1' )
304+ return pd .DataFrame (cmat , index = idx , columns = orb )
305+ return self .groupby ('irrep' ).get_group (irrep
306+ ).pivot ('chi' , 'orbital' , column )
239307 sq = _square (self [column ].values )
240- return pd .DataFrame (sq , index = pd .Index (range (sq .shape [0 ]), name = 'chi0' ),
241- columns = pd .Index (range (sq .shape [1 ]), name = 'chi1' ))
308+ idx = pd .Index (range (sq .shape [0 ]), name = 'chi0' )
309+ orb = pd .Index (range (sq .shape [1 ]), name = 'chi1' )
310+ return pd .DataFrame (sq , index = idx , columns = orb )
242311
243312 @classmethod
244313 def from_column (cls , source ):
0 commit comments