Example #1
0
    def done(self):
        """
        Run when GUI is exited. Cleanly terminates the dataset 
        with NaN values.
        """

        dStamp = dateStamp()
        # If the dataset was being logged.
        if self.hasData:

            depvars = []
            vars = []
            vars.append(dStamp.utcNowFloat())
            # Append NaN.
            try:
                for y in range(1, self.dataSet.getParameter("DataWidth")):
                    depvars.append(float(np.nan))

                newdepvars = [
                    getattr(np, self.dataType)(var) for var in depvars
                ]
                vars.extend(newdepvars)
                print "appending:", vars
                self.dataSet.addData([vars])
            except:
                traceback.print_exc()
    def save(self):
        '''Stores the data'''
        # For all datasets, check if there are readings
        #for i in range(0, len(self.devices)):

        if(self.device.getFrame().getReadings()
            is not None):
            # If the device did not have any readings and now it does
            # then we want to create a dataset.
            if(not self.hasData):
                self.configureDataSets()
        # For all datasets      
       # for i in range(0, len(self.dataSets)):
            # If there is data in this dataset
        if(self.hasData):
            depvars = []
            indepvars = []
            vars = []
            readings = []
            # Get the newest data
            #print self.devices[i].getFrame().getReadings()

            for y in range(0, len(self.device.getFrame()
                .getNicknames())):
                
                # This checks if the reading is displayed on the GUI
                # if it is not, then it does not include it in the 
                # dataset.
                if(self.device.getFrame().getNicknames()
                    [y] is not None):
                    # If the device has readings
                    if(self.device.getFrame().getReadings() is not None):
                        if(self.device.getFrame().getReadings()[y]
                            is not None):
                            readings.append(float(self.device
                                .getFrame().getReadings()[y]))
                        else:
                            readings.append(np.nan)
                    else:
                        readings.append(np.nan)
            dStamp = dateStamp()
            # If the device has readings, add data to dataset
            if(readings is not None):
                indepvars.append(dStamp.utcNowFloat())
                depvars.extend(readings)
                vars.extend(indepvars)
                vars.extend(depvars)
                varslist = self.dataSet.getVariables()
                try:
                    self.dataSet.addData([vars])
                except:
                    print self.device.getFrame().getTitle()+( 
                        "ERROR: could not store data, this might be due "
                        "to a change made to the parameters of the device, "
                        "if this is the case thene either delete the " 
                        "data set from the current storage directory or "
                        "move it somewhere else."
                    )    
 def done(self):
     '''Run when GUI is exited. Cleanly terminates the dataset 
     with Nan values.'''
     dStamp = dateStamp()
    
         # If the dataset was being logged
     if(self.hasData):
         vars = []
         vars.append(dStamp.utcNowFloat())
         # Append Nan
         for y in range(1, self.dataSet.getParameter("DataWidth")):
             vars.append(np.nan)
         #print(vars)
         self.dataSet.addData([vars])
Example #4
0
    def __init__(self, device, **kwargs):
        """Initiallize the dataChest."""
        # Define the current time.

        now = dt.datetime.now()
        # Create a devices reference that can be accessed
        # outside of this scope.
        self.device = device
        self.device.getFrame().setDataChestWrapper(self)
        # These arrays will hold all dataChest data sets.
        self.dataSet = None

        # The done function must be called when the GUI exits.
        self.dataType = kwargs.get("data_type", 'float32')
        self.dataSet = None
        self.hasData = False
        self.keepLoggingNan = True
        self.dStamp = dateStamp()
        self.restoreState()
Example #5
0
    def plot(self, timeRange):
        if not self.hidden:
            if timeRange != self.currTimeRange:
                self.timer.stop()
                self.timer.timeout.disconnect()
                self.currTimeRange = timeRange
                self.timer.timeout.connect(lambda: self.plot(self.currTimeRange))
                self.timer.start(self.refreshRateSec * 1000)
            if self.refreshRateSec != self.device.getFrame().getPlotRefreshRate():
                # print "New plot refresh rate: ", self.device.getFrame().getPlotRefreshRate()
                self.refreshRateSec = self.device.getFrame().getPlotRefreshRate()
                self.timer.stop()
                self.timer.timeout.disconnect()
                self.currTimeRange = timeRange
                self.timer.timeout.connect(lambda: self.plot(self.currTimeRange))
                self.timer.start(self.refreshRateSec * 1000)
            dataSet = self.device.getFrame().getDataSet()
            # If the dataset exists
            if dataSet is not None:
                # Get all data from the dataset
                data = dataSet.getData()
                self.ax.hold(False)
                try:
                    # for each entry in the dataset [[time], [[data], [data], [data...]]]
                    # print data
                    # Get the corresponding times that the values were recorded

                    for i in range(1, len(data[-1])):
                        # Get colum. aka all values from parameter i over time
                        column = [row[i] for row in data]

                        # print times
                        # If the there is  no defined a time range
                        if self.currTimeRange is None:
                            times = [datetime.datetime.fromtimestamp(row[0]) for row in data]
                            # Plot all of the data (columns) vs time
                            # self.ax.plot_date(times, column, label =
                            # dataSet.getVariables()[1][i-1][0])
                            pass
                        else:
                            # Otherwise, if the user PREVIOUSLY defined a time range,
                            # we need to look for the beginning of it.
                            # Start by getting the current time
                            dstamp = dateStamp()
                            # The dataset should be from now to -timerange
                            # time(now)-time(range)
                            startTime = dstamp.utcNowFloat() - self.currTimeRange
                            # If timeRange is not None, then we know we need
                            # to display only a certain range of values
                            # However, if the starttime defined is less than the lowest time, we
                            # do not have enough data to display the whole thing, so we must
                            # display all that we have instead. We do this by setting
                            # currTimeRange = 0.
                            if timeRange is not None and startTime < float(data[0][0]):
                                self.currTimeRange = None
                            # For all entries in data
                            for y in range(len(data)):
                                # We are searching backwards through the dataset to find a time
                                # just before the time range specified
                                if data[len(data) - y - 1][0] < startTime:
                                    # once we find it, we know the beginning index of the data to be
                                    # displayed
                                    index = y
                                    # Get the times and datafrom the index and columns to the end of the dataset
                                    times = [datetime.datetime.fromtimestamp(row[0]) for row in data[-index:]]
                                    # print times[0]
                                    column = [row[i] for row in data[-index:]]
                                    # Exit the loop
                                    break

                        try:
                            while len(self.line) <= i:
                                self.line.append(self.ax.plot(1, 1, label=dataSet.getVariables()[1][i - 1][0])[0])

                            self.line[i].set_data(times, column)
                            self.ax.legend(loc="upper left", shadow=True, fancybox=True)
                            # maxi = max(column)
                            # mini = min(column)
                            # newMax = max(column)
                            # newMini = min(column)
                            # if(newMax>maxi)
                            # maxi=newMax
                            # self.ax.set_ylim(mini-mini/2, maxi+maxi/2)
                            # if(newMini<mini)
                            # self.ax.set_ylim(mini-mini/2, maxi+maxi/2)
                            # maxi = max(column)
                            # mini = min(column)

                            # self.ax.set_ylim(mini-mini/2, maxi+maxi/2)
                            # self.ax.set_xlim(min(times), max(times))
                            # self.ax.draw_artist(self.line[i])
                        except:

                            traceback.print_exc()

                            # print "Failed to log data"
                        # Add a legend
                        legend = self.ax.legend(loc="upper left")
                        self.ax.set_title(
                            self.device.getFrame().getTitle(), color=(189.0 / 255, 195.0 / 255, 199.0 / 255)
                        )

                        if (
                            self.device.getFrame().getYLabel() is not None
                            and len(self.device.getFrame().getCustomUnits()) is not 0
                        ):
                            self.ax.set_ylabel(
                                self.device.getFrame().getYLabel()
                                + " ("
                                + self.device.getFrame().getCustomUnits()
                                + ")"
                            )
                        elif (
                            self.device.getFrame().getYLabel() is not None
                            and len(self.device.getFrame().getUnits()[i - 1]) is not 0
                        ):

                            self.ax.set_ylabel(
                                self.device.getFrame().getYLabel()
                                + " ("
                                + self.device.getFrame().getUnits()[i - 1]
                                + ")"
                            )

                        self.ax.set_xlabel("Time")

                        self.ax.hold(True)
                        # locator = AutoDateLocator()
                        # self.ax.fmt_xdata = AutoDateFormatter()
                        # self.ax.xaxis.set_major_locator(locator)
                        # self.ax.xaxis.set_major_locator(locator)
                        # self.ax.xaxis.set_major_formatter(DateFormatter('%m/%d'))

                        # self.ax.fmt_xdata = mdates.DateFormatter('%m/%d %H:%M:%S')
                        # print "type: ", type(times[-1])
                        # print "time[-1]: ",times[-1]
                        # self.ax.set_ylim(bottom = 733681, top = 733682)

                        # self.figure.tight_layout()
                        self.ax.grid(True)

                except Exception as e:
                    print "Error"
                try:

                    self.ax.grid(True)
                    # self.ax.clear(self.ax.yaxis)
                    # self.ax.cla()

                    if self.home:
                        self.ax.set_xlim(times[0], times[-1])
                        self.ax.relim()
                        self.ax.autoscale()

                    # print self.ax.get_data_interval()
                    self.ax.draw_artist(self.figure)
                    self.ax.draw_artist(self.ax.patch)

                    locator = AutoDateLocator()

                    self.ax.xaxis.set_major_locator(locator)
                    self.ax.xaxis.set_major_formatter(DateFormatter("%m/%d %H:%M:%S"))
                    self.figure.autofmt_xdate()
                    # print [time.toordinal() for time in times]
                    self.ax.draw_artist(self.ax.yaxis)
                    self.ax.draw_artist(self.ax.xaxis)

                    for line in self.line:
                        self.ax.draw_artist(line)

                    # self.ax.axis('off')

                    self.ax.draw_artist(legend)

                    self.canvas.update()

                    self.canvas.flush_events()

                except:
                    times = [datetime.datetime.fromtimestamp(row[0]) for row in data]
                    traceback.print_exc()
                    self.ax.set_xlim(times[0], times[-1])
                    self.ax.relim()
                    self.ax.autoscale()
                    # print self.ax.get_data_interval()
                    pass
    def configureDataSets(self):
        '''Initialize the datalogger, if datasets already 
        exist, use them. Otherwise create new ones.'''
        now = datetime.datetime.now()
        self.hasData = True
        # Generate a title for the dataset. NOTE: if 
        # the title of the device is changed in the device's constructor
        # in the main class, then a different data set will be created. 
        # This is because datasets are stored using the name of the device,
        # which is what the program looks for when checking if there are
        # data files that already exist.
        title = str(self.device.getFrame().getTitle()).replace(" ", "")
        # Datasets are stored in the folder 'DATA_CHEST_ROOT\year\month\'
        # Try to access the current month's folder, if it does not exist, 
        # make it.
        try:
            self.dataSet.cd(str(now.month))
        except:
            self.dataSet.mkdir(str(now.month))
            self.dataSet.cd(str(now.month))

        try:
            self.dataSet.cd(str(int(now.day/7)))
        except:
            self.dataSet.mkdir(str(int(now.day/7)))
            self.dataSet.cd(str(int(now.day/7)))

        # Look at the names of all existing datasets and check if the 
        # name contains the title of the current device. 
        existingFiles = self.dataSet.ls()
        # foundit becomes true if a dataset file already exists
        foundit = False
        # Go through all existing dataset files
        for y in range(0, len(existingFiles[0])):
            # If the name of the file contains the (persistant) title 
            # generated by the code, open that dataset and use it.
            
            if(title in existingFiles[0][y]):
                self.dataSet.openDataset(existingFiles[0][y], 
                    modify = True)
                foundit = True
            # if(foundit):
                print("Existing data set found for "+title+": "
                    +existingFiles[0][y])
        if(foundit):
            pass
        # If the dataset does not already exist, we must create it.
        else:
            print("Creating dataset for "+title)
            # Name of the parameter. This is the name of the parameter
            # displayed on the gui except without spaces or 
            # non-alphanumerical characters.
            paramName = None
            # Arrays to hold any variables
            depvars = []
            indepvars = []
            # For each device, assume it is not connected and we should not log
            # data until the gui actually gets readings.
            # Loop through all parameters in the device
            for y in range (0, len(self.device.getFrame().getNicknames())):
                # If the name of the parameter has not been defined as None 
                # in the constructor, then we want to log it.
                if(self.device.getFrame().getNicknames()[y] is not None):
                    # The name of the parameter in the dataset is the same 
                    # name displayed on the GUI except without 
                    # non-alphanumerical characters. Use regular expressions
                    # to do this.
                    paramName = str(self.device.getFrame().getNicknames()
                        [y]).replace(" ","")
                    paramName = re.sub(r'\W+', '', paramName)
                    # Create the tuple that defines the parameter.
                    tup = (paramName, [1], "float64", str(self.device
                        .getFrame().getUnits()[y]))
                    # Add it to the array of dependent variables
                    depvars.append(tup)
            # Get the datestamp from the datachest helper class.
            dStamp = dateStamp()
            # Time is the only independent variable
            indepvars.append(("time", [1], "utc_datetime", "s"))
            # The vars variable holds ALL variables
            vars = []
            vars.extend(indepvars)
            vars.extend(depvars)
            # Construct the data set
            #print indepvars
            #print depvars
            self.dataSet.createDataset(title, indepvars, depvars)
            # The datawidth parameter says how many variables 
            # (independent and dependent) make up the dataset.
            # DataWidth is used internally only.
            self.dataSet.addParameter("DataWidth", len(vars))
            if(self.device.getFrame().getYLabel() is not None):
                # Configure the label of the y axis given in the device'same
                # constructor.
                self.dataSet.addParameter("Y Label", self.device
                    .getFrame().getYLabel())
        self.device.getFrame().setDataSet(self.dataSet)
Example #7
0
    def configureDataSets(self, **kwargs):
        """
        Initialize the datalogger, if datasets already exist, use them.
        Otherwise create new ones.
        """

        now = dt.datetime.now()
        # Force creation of new dataset?
        force_new = kwargs.get('force_new', False)
        self.hasData = True
        # Generate a title for the dataset. NOTE: if
        # the title of the device is changed in the device's constructor
        # in the main class, then a different data set will be created.
        # This is because datasets are stored using the name of
        # the device, which is what the program looks for when checking
        # if there are data files that already exist.
        title = str(self.device.getFrame().DataLoggingInfo()['name']).replace(
            " ", "_")
        # Datasets are stored in the folder 'DATA_CHEST_ROOT\year\month\'
        # Try to access the current month's folder, if it does not
        # exist, make it.
        location = self.device.getFrame().DataLoggingInfo()['location']
        # print "Location1:", location
        # root = os.environ['DATA_CHEST_ROOT']
        # relativePath =  os.path.relpath(root, dir)
        # print "Configuring datalogging for", str(self.device)+" located at",
        # location

        if location != None:
            root = os.environ['DATA_CHEST_ROOT']
            root = root.replace("/", "\\")
            relativePath = os.path.relpath(location, root)
            #print "relativePath:", relativePath
            #if relativePath == '.':
            #   raise IOError(
            #       "Cannot create dataset directly under DATA_CHEST_ROOT.")
            path = relativePath.split("\\")
            if force_new:

                try:
                    print "Could not store in:", path[-1]

                    folder_version = int(path[-1][path[-1].index('__') + 2::])
                    path[-1] = path[-1][:path[-1].index('__')]
                    folder_version += 1
                    path[-1] += str('__' + str(folder_version))
                except:
                    traceback.print_exc()
                    path[-1] += '__0'
                #print str(self.device)+":", "New data location forced:", path
            print "Path:", path
            self.dataSet = dataChest(str(path[0]))
            self.dataSet.cd('')
            # relativepath = os.path.relpath(
            #    location, self.dataSet.pwd().replace("/", "\\"))
            # path = relativePath.split("\\")

            #print "path:", str(path)
            # dateFolderName = time.strftime('%x').replace(' ', '_')
            # dateFolderName = dateFolderName.replace('/', '_')
            folder_version = 0
            #path[-1]+=str("__"+str(folder_version))

            for folder in path[1::]:
                try:
                    #print "folder:", folder
                    self.dataSet.cd(folder)
                except:
                    try:
                        self.dataSet.mkdir(folder)
                        self.dataSet.cd(folder)

                    except:
                        print "ERROR: Could not create dataset at:", path
                        #folder_version += 1
                        #path[-1] = folder[0:folder.index('__')]+str("__"+str(folder_version))

                        traceback.print_exc()

            # print "Configuring datalogging for", str(self.device)+" located
            # at", location
        if location == None:
            folderName = time.strftime('%x').replace(' ', '_')
            folderName = folderName.replace('/', '_')

            self.dataSet = dataChest(folderName)
            # try:
            # self.dataSet.cd(folderName)
            # except:
            # self.dataSet.mkdir(folderName)
            # self.dataSet.cd(folderName)
            try:
                self.device.getFrame().DataLoggingInfo(
                )['location'] = os.path.abspath(self.dataSet.pwd())
            except:
                traceback.print_exc()

        # Look at the names of all existing datasets and check
        # if the name contains the title of the current device.
        existingFiles = self.dataSet.ls()
        # foundit becomes true if a dataset file already exists.
        foundit = False
        # Go through all existing dataset files.
        for y in range(len(existingFiles[0])):
            # If the name of the file contains the (persistant) title
            # generated by the code, open that dataset and use it.
            if title in existingFiles[0][y]:
                self.dataSet.openDataset(existingFiles[0][y], modify=True)

                foundit = True
                # If the number of variables in the data set has changed since last time,
                # Then we do not want to use the old dataset.

                if len(self.dataSet.getVariables()[1]) != len(
                        self.device.getFrame().getNicknames()):

                    foundit = False
                else:
                    # print("Existing data set found for %s: %s."
                    #   %(title, existingFiles[0][y]))
                    pass
        # If the dataset does not already exist, we must create it.
        if not foundit:
            # print("Creating dataset for %s." %title)
            # Name of the parameter. This is the name of the parameter
            # displayed on the gui except without spaces or
            # non-alphanumerical characters.
            paramName = None
            # Arrays to hold any variables.
            depvars = []
            indepvars = []
            # For each device, assume it is not connected and we should
            # not log data until the GUI actually gets readings.
            # Loop through all parameters in the device.
            # print "Setting up datalogging for device",
            # self.device.getFrame().getTitle()
            nicknames = self.device.getFrame().getNicknames()
            # print "Nicknames:", self.device.getFrame().getNicknames()
            for y, name in enumerate(nicknames):
                # If the name of the parameter has not been defined as
                # None in the constructor, then we want to log it.
                if name is not None:
                    # The name of the parameter in the dataset is
                    # the same name displayed on the GUI except without
                    # non-alphanumerical characters. Use regular
                    # expressions to do this.
                    paramName = str(name).replace(" ", "_")
                    paramName = re.sub(r'\W+', '', paramName)
                    # Create the tuple that defines the parameter.
                    # print self.device, "device units: ", self.device.getFrame().getUnits()
                    # print "nicknames:", nicknames
                    #print self.device, "datatype:", self.dataType
                    tup = (paramName, [1], self.dataType,
                           str(self.device.getUnit(name)))
                    # Add it to the array of dependent variables.
                    depvars.append(tup)
            # Get the datestamp from the datachest helper class.
            dStamp = dateStamp()
            # Time is the only independent variable.
            indepvars.append(("time", [1], "utc_datetime", "s"))
            # The vars variable holds ALL variables.
            vars = []
            vars.extend(indepvars)
            vars.extend(depvars)
            # Construct the data set
            self.dataSet.createDataset(title, indepvars, depvars)
            # The DataWidth parameter says how many variables
            # (independent and dependent) make up the dataset.
            # DataWidth is used internally only.
            self.dataSet.addParameter("DataWidth", len(vars))

            # if self.device.getFrame().getYLabel() is not None:
            # Configure the label of the y axis given in the
            # device's constructor.
        self.device.getFrame().DataLoggingInfo(
        )['location'] = self.dataSet.pwd()
        self.device.getFrame().setDataSet(self.dataSet)