def pdos_select( self, atoms=None, spin=None, l=None, m=None ):
        valid_m_values = { 's': [],
                           'p': [ 'x', 'y', 'z' ],
                           'd': [ 'xy', 'yz', 'z2-r2', 'xz', 'x2-y2' ],
                           'f': [ 'y(3x2-y2)', 'xyz', 'yz2', 'z3', 'xz2', 'z(x2-y2)', 'x(x2-3y2)' ] }
        if not atoms:
            atom_idx = list(range( self.number_of_atoms ))
        else:
            atom_idx = atoms
        to_return = self.pdos[ atom_idx, :, :, : ]
        if not spin:
            spin_idx = list(range( self.ispin ))
        elif spin is 'up':
            spin_idx = [0]
        elif spin is 'down':
            spin_idx = [1]
        elif spin is 'both':
            spin_idx = [0,1]
        else:
            raise ValueError( "valid spin values are 'up', 'down', and 'both'. The default is 'both'" )
        to_return = to_return[ :, :, :, spin_idx ]
        if not l:
            channel_idx = list(range( self.number_of_channels ))
        elif l == 's':
            channel_idx = [ 0 ]
        elif l == 'p':
            if not m:
                channel_idx = [ 1, 2, 3 ]
            else:
                channel_idx = [ i+1 for i, v in enumerate( valid_m_values['p'] ) if v in m ]
        elif l == 'd':
            if not m:
                channel_idx = [ 4, 5, 6, 7, 8 ]
            else:
                channel_idx = [ i+4 for i, v in enumerate( valid_m_values['d'] ) if v in m ]
        elif l == 'f':
            if not m:
                channel_idx = [ 9, 10, 11, 12, 13, 14, 15 ]
            else:
                channel_idx = [ i+9 for i, v in enumerate( valid_m_values['f'] ) if v in m ]
        else:
            raise ValueError
        return to_return[ :, :, channel_idx, : ]