def __init__(self, fname, plist, args=None):
        """ Takes a file name to json formatted data
        with a bunch of stations as primary attributes, each with
        a value that is also an attribute. whatever"""
        self._stns = []  # Base data
        self.stns = []  # Filtered data
        self.plist = plist
        # scoper provides some utilites for working with scoped declarations for
        # accessing deep json structures
        self.scp = Scoper("::")

        self.data = json.loads(open(fname).read())

        if args:
            self.filter(args)
        else:
            self.setBaseData(self.data)
    def __init__(self, fname, plist, args = None):
        """ Takes a file name to json formatted data
        with a bunch of stations as primary attributes, each with
        a value that is also an attribute. whatever"""
        self._stns = [] # Base data
        self.stns = [] # Filtered data
        self.plist = plist
        # scoper provides some utilites for working with scoped declarations for
        # accessing deep json structures
        self.scp = Scoper("::")

        self.data = json.loads( open(fname).read() )

        if args:
            self.filter(args)
        else:
            self.setBaseData(self.data)
class Params(object):
    def __init__(self, fname, plist, args=None):
        """ Takes a file name to json formatted data
        with a bunch of stations as primary attributes, each with
        a value that is also an attribute. whatever"""
        self._stns = []  # Base data
        self.stns = []  # Filtered data
        self.plist = plist
        # scoper provides some utilites for working with scoped declarations for
        # accessing deep json structures
        self.scp = Scoper("::")

        self.data = json.loads(open(fname).read())

        if args:
            self.filter(args)
        else:
            self.setBaseData(self.data)

    def setBaseData(self, data):
        """ Set data as base data from which a reset() will return state"""
        self._stns = []
        for stn in data.keys():
            # Make sure all parameters exist for each station
            # If they do, add station to list.
            # Use the scoper to flatten json so we can check if
            # scoped keys are in the dictionary. (allows us to search with
            # depth into dictionary a::b = d['a']['b']
            if len([
                    p for p in self.plist
                    if p in self.scp.flattendict(data[stn])
            ]) == len(self.plist):
                self._stns.append(stn)

        # Make self._stns immutable
        self._stns = tuple(self._stns)

        # Create a temporary dictionary of all
        # station data.
        temp = {}
        for p in self.plist:
            temp[p] = np.zeros(len(self._stns))
        for ii, stn in enumerate(self._stns):
            for p in self.plist:
                temp[p][ii] = self.scp.flattendict(data[stn])[p]

        # Build base data variables with _ prefix as
        # numpy data extracted from json data.
        for p in self.plist:
            setattr(self, '_' + self.scp.normscope(p), temp[p])

        # Build variable list, initial array order is just
        # station order
        self.reset()

    def filter(self, args):
        """ Use querystns function from dbutils to refine basedata."""
        self.data = queryStns(self.data, args, self.scp)
        if not len(self.data):
            print "Query returned empty dictionary"
        self.setBaseData(self.data)

    def sync(self, pobj):
        """ Filter by list of stations only, useful for syncing
        with another Param object station list. The incoming
        station list must be subset of object station list or an
        error is raised."""
        #        stns = []
        myIndx = []
        yourIndx = []
        # Scan down callee's station list
        for ind, stn in enumerate(pobj.stns):
            # Look for the stn in the callee and find the index in self
            ix = find(self.stns, stn)
            # If we don't have a stn, we skip an ind in the callee's index list
            if ix == -1:
                pass
            else:
                myIndx.append(ix)
                yourIndx.append(ind)

        pobj.orderAttribs(yourIndx)
        self.orderAttribs(myIndx)
        # For chaining
        return self

    def orderAttribs(self, newindex):
        """ Take a list of index of length len(self.stns)
        holding indice numbers to reorganize attribute vectors"""
        # For each base attribute make a new attribute with name minus underscore
        # which has the value of the inds sorted array.
        # The index to sort by must relate to the initial index
        # by continuing to pass the same rearranged list. (through
        # modification of self.index)

        self.index = np.take(self.index, newindex)
        self.stns = np.take(self._stns, self.index)
        for p in self.plist:
            setattr(
                self, self.scp.normscope(p),
                np.take(getattr(self, '_' + self.scp.normscope(p)),
                        self.index))

    def reset(self):
        self.index = [i for i in range(len(self._stns))]
        self.orderAttribs(self.index)
        return self
class Params(object):
    def __init__(self, fname, plist, args = None):
        """ Takes a file name to json formatted data
        with a bunch of stations as primary attributes, each with
        a value that is also an attribute. whatever"""
        self._stns = [] # Base data
        self.stns = [] # Filtered data
        self.plist = plist
        # scoper provides some utilites for working with scoped declarations for
        # accessing deep json structures
        self.scp = Scoper("::")

        self.data = json.loads( open(fname).read() )

        if args:
            self.filter(args)
        else:
            self.setBaseData(self.data)


    def setBaseData(self, data):
        """ Set data as base data from which a reset() will return state"""
        self._stns = []
        for stn in data.keys():
            # Make sure all parameters exist for each station
            # If they do, add station to list.
            # Use the scoper to flatten json so we can check if
            # scoped keys are in the dictionary. (allows us to search with
            # depth into dictionary a::b = d['a']['b']
            if len([p for p in self.plist if p in self.scp.flattendict(data[stn])]) == len(self.plist):
                self._stns.append(stn)

        # Make self._stns immutable
        self._stns = tuple(self._stns)

        # Create a temporary dictionary of all
        # station data.
        temp = {}
        for p in self.plist:
            temp[p] = np.zeros(len(self._stns))
        for ii, stn in enumerate(self._stns):
            for p in self.plist:
                temp[p][ii] = self.scp.flattendict(data[stn])[p]

        # Build base data variables with _ prefix as
        # numpy data extracted from json data.
        for p in self.plist:
            setattr(self, '_' + self.scp.normscope(p), temp[p])

        # Build variable list, initial array order is just
        # station order
        self.reset()


    def filter(self, args):
        """ Use querystns function from dbutils to refine basedata."""
        self.data = queryStns(self.data, args, self.scp)
        if not len(self.data):
            print "Query returned empty dictionary"
        self.setBaseData(self.data)

    def sync(self, pobj):
        """ Filter by list of stations only, useful for syncing
        with another Param object station list. The incoming
        station list must be subset of object station list or an
        error is raised."""
#        stns = []
        myIndx = []
        yourIndx = []
        # Scan down callee's station list
        for ind, stn in enumerate(pobj.stns):
            # Look for the stn in the callee and find the index in self
            ix = find(self.stns, stn)
            # If we don't have a stn, we skip an ind in the callee's index list
            if ix == -1:
                pass
            else:
                myIndx.append(ix)
                yourIndx.append(ind)

        pobj.orderAttribs(yourIndx)
        self.orderAttribs(myIndx)
        # For chaining
        return self

    def orderAttribs(self, newindex):
        """ Take a list of index of length len(self.stns)
        holding indice numbers to reorganize attribute vectors"""
        # For each base attribute make a new attribute with name minus underscore
        # which has the value of the inds sorted array.
        # The index to sort by must relate to the initial index
        # by continuing to pass the same rearranged list. (through
        # modification of self.index)

        self.index = np.take(self.index, newindex)
        self.stns = np.take(self._stns, self.index)
        for p in self.plist:
            setattr(self, self.scp.normscope(p),
                    np.take(getattr(self, '_'+ self.scp.normscope(p)),
                            self.index))


    def reset(self):
        self.index = [i for i in range(len(self._stns))]
        self.orderAttribs(self.index)
        return self