예제 #1
0
    def calculate_from_measured(self, forcePeriodCalc=False):
        '''Calculates the parameters from measured data.'''

        rawDataDir = os.path.join(self.directory, 'RawData')
        pathToRawFile = os.path.join(rawDataDir,
                                     self.bicycleName + 'Measured.txt')

        # load the measured parameters
        self.parameters['Measured'] = io.load_parameter_text_file(
            pathToRawFile)

        forkIsSplit = is_fork_split(self.parameters['Measured'])

        # if the the user doesn't specifiy to force period calculation, then
        # see if enough data is actually available in the *Measured.txt file to
        # do the calculations
        if not forcePeriodCalc:
            forcePeriodCalc = period.check_for_period(
                self.parameters['Measured'], forkIsSplit)

        if forcePeriodCalc == True:
            # get the list of mat files associated with this bike
            matFiles = [
                x for x in os.listdir(rawDataDir) if x.endswith('.mat')
            ]
            matFiles.sort()
            # calculate the period for each file for this bicycle
            periods = period.calc_periods_for_files(rawDataDir, matFiles,
                                                    forkIsSplit)
            # add the periods to the measured parameters
            self.parameters['Measured'].update(periods)

            io.write_periods_to_file(pathToRawFile, periods)

        return calculate_benchmark_from_measured(self.parameters['Measured'])
예제 #2
0
    def calculate_from_measured(self, forcePeriodCalc=False):
        '''Calculates the parameters from measured data.'''

        rawDataDir = os.path.join(self.directory, 'RawData')
        pathToRawFile = os.path.join(rawDataDir, self.bicycleName + 'Measured.txt')

        # load the measured parameters
        self.parameters['Measured'] = io.load_parameter_text_file(pathToRawFile)

        forkIsSplit = is_fork_split(self.parameters['Measured'])

        # if the the user doesn't specifiy to force period calculation, then
        # see if enough data is actually available in the *Measured.txt file to
        # do the calculations
        if not forcePeriodCalc:
            forcePeriodCalc = period.check_for_period(self.parameters['Measured'],
                                               forkIsSplit)

        if forcePeriodCalc == True:
            # get the list of mat files associated with this bike
            matFiles = [x for x in os.listdir(rawDataDir)
                        if x.endswith('.mat')]
            matFiles.sort()
            # calculate the period for each file for this bicycle
            periods = period.calc_periods_for_files(rawDataDir, matFiles, forkIsSplit)
            # add the periods to the measured parameters
            self.parameters['Measured'].update(periods)

            io.write_periods_to_file(pathToRawFile, periods)

        return calculate_benchmark_from_measured(self.parameters['Measured'])
예제 #3
0
    def __init__(self,
                 bicycleName,
                 pathToData='.',
                 forceRawCalc=False,
                 forcePeriodCalc=False):
        """
        Creates a bicycle object and sets the parameters based on the available
        data.

        Parameters
        ----------
        bicycleName : string
            The short name of your bicicleta. It should be one word with the
            first letter capitalized and all other letters lower case. You
            should have a matching directory under `<pathToData>/bicycles/`.
            For example: `<pathToData>/bicycles/Shortname`.
        pathToData : string
            This is the path to the folder where the bicycle/rider parameters
            and raw data are stored. The default is the current working
            directory.
        forceRawCalc : boolean
            Forces a recalculation of the benchmark parameters from the measured
            parameters. Otherwise it will only run the calculation if there is
            no benchmark parameter file.
        forcePeriodCalc : boolean
            Forces a recalculation of the periods from the oscillation data.

        Notes
        -----
        Bicycles are assumed not to have a rider when initially loaded.

        """

        self.bicycleName = bicycleName
        pathToBicycles = os.path.join(pathToData, 'bicycles')
        # the directory where the files for this bicycle are stored
        self.directory = os.path.join(pathToBicycles, bicycleName)

        # bicycles are assumed not to have a rider when initially loaded
        self.hasRider = False
        self.riderPar = {}
        self.human = None

        self.parameters = {}
        # if there are some parameter files, then load them
        if 'Parameters' in os.listdir(self.directory):
            parDir = os.path.join(self.directory, 'Parameters')
            parFiles = os.listdir(parDir)
            for parFile in parFiles:
                # remove the extension
                fname = os.path.splitext(parFile)[0]
                # get the bike and the parameter set type
                bike, ptype = io.space_out_camel_case(fname, output='list')
                # load the parameters
                pathToFile = os.path.join(parDir, parFile)
                self.parameters[ptype] = io.load_parameter_text_file(
                    pathToFile)

        # this is where the raw data files from the pendulum oscillations are
        # stored
        rawDataDir = os.path.join(self.directory, 'RawData')

        # it would be more robust to see if there are enough files in the
        # RawData directory, but that isn't implemented yet. For now you'll
        # just get and error sometime down the road when a period for the
        # missing files is needed.
        isRawDataDir = 'RawData' in os.listdir(self.directory)

        if isRawDataDir:
            print "Found the RawData directory:", rawDataDir
            isMeasuredFile = bicycleName + 'Measured.txt' in os.listdir(
                rawDataDir)
        else:
            isMeasuredFile = False

        isBenchmark = 'Benchmark' in self.parameters.keys()

        # the user wants to force a recalc and the data is there
        conOne = forceRawCalc and isRawDataDir and isMeasuredFile
        # the user doesn't want to force a recalc and there are no benchmark
        # parameters
        conTwo = not forceRawCalc and not isBenchmark

        if conOne or conTwo:
            print "Recalcuting the parameters."
            par, extras = self.calculate_from_measured(
                forcePeriodCalc=forcePeriodCalc)
            self.parameters['Benchmark'] = par
            self.extras = extras
            print("The glory of the %s parameters are upon you!" %
                  self.bicycleName)
        elif not forceRawCalc and isBenchmark:
            # we already have what we need
            stmt1 = "Looks like you've already got some parameters for %s, "
            stmt2 = "use forceRawCalc to recalculate."
            print(stmt1 + stmt2) % self.bicycleName
            # load the measured.txt file if it exists
            pathToRawFile = os.path.join(rawDataDir,
                                         self.bicycleName + 'Measured.txt')
            try:
                self.parameters['Measured'] = \
                        io.load_parameter_text_file(pathToRawFile)
            except IOError:
                pass
        else:
            print '''There is no data available. Create
            bicycles/{sn}/Parameters/{sn}Benchmark.txt and/or fill
            bicycle/{sn}/RawData/ with pendulum data mat files and the
            {sn}Measured.txt file'''.format(sn=bicycleName)
예제 #4
0
    def add_rider(self, riderName, reCalc=False, draw=False):
        """
        Adds the inertial effects of a rigid rider to the bicycle.

        Parameters
        ----------
        riderName : string
            A rider name that corresponds to a folder in
            `<pathToData>/riders/`.
        reCalc : boolean, optional
            If true, the rider parameters will be recalculated.
        draw : boolean, optional
            If true, visual python will be used to draw a three dimensional
            image of the rider.

        """

        # can't draw the rider model without the human object
        if draw:
            reCalc = True

        # first check to see if a rider has already been added
        if self.hasRider == True:
            print(("D'oh! This bicycle already has {0} as a " +
                   "rider!").format(self.riderName))
        else:
            print("There is no rider on the bicycle, now adding " +
                  "{0}.".format(riderName))
            pathToData = os.path.split(os.path.split(self.directory)[0])[0]
            # get the path to the rider's folder
            pathToRider = os.path.join(pathToData, 'riders', riderName)
            # load in the parameters
            bicyclePar = self.parameters['Benchmark']
            bicycleName = self.bicycleName

            if reCalc == True:
                print("Calculating the human configuration.")
                # run the calculations
                try:
                    measuredPar = self.parameters['Measured']
                except KeyError:
                    print('The measured bicycle parameters need to be ' +
                          'available, create your bicycle such that they ' +
                          'are available.')
                    raise
                riderPar, human, bicycleRiderPar =\
                    rider.configure_rider(pathToRider, bicycleName, bicyclePar,
                            measuredPar, draw)
            else:
                pathToParFile = os.path.join(
                    pathToRider, 'Parameters',
                    riderName + self.bicycleName + 'Benchmark.txt')
                try:
                    # load the parameter file
                    riderPar = io.load_parameter_text_file(pathToParFile)
                except IOError:
                    # file doesn't exist so run the calculations
                    print("No parameter files found, calculating the human " +
                          "configuration.")
                    try:
                        measuredPar = self.parameters['Measured']
                    except KeyError:
                        print(
                            'The measured bicycle parameters need to be ' +
                            'available, create your bicycle such that they ' +
                            'are available.')
                        raise
                    riderPar, human, bicycleRiderPar =\
                        rider.configure_rider(pathToRider, bicycleName,
                                bicyclePar, measuredPar, draw)
                else:
                    print("Loaded the precalculated parameters from " +
                          "{0}".format(pathToParFile))
                    bicycleRiderPar = inertia.combine_bike_rider(
                        bicyclePar, riderPar)
            # set the attributes
            self.riderPar['Benchmark'] = riderPar
            try:
                self.human = human
            except NameError:
                self.human = None
            self.parameters['Benchmark'] = bicycleRiderPar
            self.riderName = riderName
            self.hasRider = True
예제 #5
0
    def __init__(self, bicycleName, pathToData='.', forceRawCalc=False,
            forcePeriodCalc=False):
        """
        Creates a bicycle object and sets the parameters based on the available
        data.

        Parameters
        ----------
        bicycleName : string
            The short name of your bicicleta. It should be one word with the
            first letter capitalized and all other letters lower case. You
            should have a matching directory under `<pathToData>/bicycles/`.
            For example: `<pathToData>/bicycles/Shortname`.
        pathToData : string
            This is the path to the folder where the bicycle/rider parameters
            and raw data are stored. The default is the current working
            directory.
        forceRawCalc : boolean
            Forces a recalculation of the benchmark parameters from the measured
            parameters. Otherwise it will only run the calculation if there is
            no benchmark parameter file.
        forcePeriodCalc : boolean
            Forces a recalculation of the periods from the oscillation data.

        Notes
        -----
        Bicycles are assumed not to have a rider when initially loaded.

        """

        self.bicycleName = bicycleName
        pathToBicycles = os.path.join(pathToData, 'bicycles')
        # the directory where the files for this bicycle are stored
        self.directory = os.path.join(pathToBicycles, bicycleName)

        # bicycles are assumed not to have a rider when initially loaded
        self.hasRider = False
        self.riderPar = {}
        self.human = None

        self.parameters = {}
        # if there are some parameter files, then load them
        if 'Parameters' in os.listdir(self.directory):
            parDir = os.path.join(self.directory, 'Parameters')
            parFiles = os.listdir(parDir)
            for parFile in parFiles:
                # remove the extension
                fname = os.path.splitext(parFile)[0]
                # get the bike and the parameter set type
                bike, ptype = io.space_out_camel_case(fname, output='list')
                # load the parameters
                pathToFile = os.path.join(parDir, parFile)
                self.parameters[ptype] = io.load_parameter_text_file(pathToFile)

        # this is where the raw data files from the pendulum oscillations are
        # stored
        rawDataDir = os.path.join(self.directory, 'RawData')

        # it would be more robust to see if there are enough files in the
        # RawData directory, but that isn't implemented yet. For now you'll
        # just get and error sometime down the road when a period for the
        # missing files is needed.
        isRawDataDir = 'RawData' in os.listdir(self.directory)

        if isRawDataDir:
            print "Found the RawData directory:", rawDataDir
            isMeasuredFile = bicycleName + 'Measured.txt' in os.listdir(rawDataDir)
        else:
            isMeasuredFile = False

        isBenchmark = 'Benchmark' in self.parameters.keys()

        # the user wants to force a recalc and the data is there
        conOne = forceRawCalc and isRawDataDir and isMeasuredFile
        # the user doesn't want to force a recalc and there are no benchmark
        # parameters
        conTwo = not forceRawCalc and not isBenchmark

        if conOne or conTwo:
            print "Recalcuting the parameters."
            par, extras = self.calculate_from_measured(
                    forcePeriodCalc=forcePeriodCalc)
            self.parameters['Benchmark'] = par
            self.extras = extras
            print("The glory of the %s parameters are upon you!"
                  % self.bicycleName)
        elif not forceRawCalc and isBenchmark:
            # we already have what we need
            stmt1 = "Looks like you've already got some parameters for %s, "
            stmt2 = "use forceRawCalc to recalculate."
            print (stmt1 + stmt2) % self.bicycleName
            # load the measured.txt file if it exists
            pathToRawFile = os.path.join(rawDataDir,
                    self.bicycleName + 'Measured.txt')
            try:
                self.parameters['Measured'] = \
                        io.load_parameter_text_file(pathToRawFile)
            except IOError:
                pass
        else:
            print '''There is no data available. Create
            bicycles/{sn}/Parameters/{sn}Benchmark.txt and/or fill
            bicycle/{sn}/RawData/ with pendulum data mat files and the
            {sn}Measured.txt file'''.format(sn=bicycleName)
예제 #6
0
    def add_rider(self, riderName, reCalc=False, draw=False):
        """
        Adds the inertial effects of a rigid rider to the bicycle.

        Parameters
        ----------
        riderName : string
            A rider name that corresponds to a folder in
            `<pathToData>/riders/`.
        reCalc : boolean, optional
            If true, the rider parameters will be recalculated.
        draw : boolean, optional
            If true, visual python will be used to draw a three dimensional
            image of the rider.

        """

        # can't draw the rider model without the human object
        if draw:
            reCalc=True

        # first check to see if a rider has already been added
        if self.hasRider == True:
            print(("D'oh! This bicycle already has {0} as a " +
                  "rider!").format(self.riderName))
        else:
            print("There is no rider on the bicycle, now adding " +
                  "{0}.".format(riderName))
            pathToData = os.path.split(os.path.split(self.directory)[0])[0]
            # get the path to the rider's folder
            pathToRider = os.path.join(pathToData, 'riders', riderName)
            # load in the parameters
            bicyclePar = self.parameters['Benchmark']
            bicycleName = self.bicycleName

            if reCalc == True:
                print("Calculating the human configuration.")
                # run the calculations
                try:
                    measuredPar = self.parameters['Measured']
                except KeyError:
                    print('The measured bicycle parameters need to be ' +
                          'available, create your bicycle such that they ' +
                          'are available.')
                    raise
                riderPar, human, bicycleRiderPar =\
                    rider.configure_rider(pathToRider, bicycleName, bicyclePar,
                            measuredPar, draw)
            else:
                pathToParFile = os.path.join(pathToRider, 'Parameters',
                    riderName + self.bicycleName + 'Benchmark.txt')
                try:
                    # load the parameter file
                    riderPar = io.load_parameter_text_file(pathToParFile)
                except IOError:
                    # file doesn't exist so run the calculations
                    print("No parameter files found, calculating the human " +
                          "configuration.")
                    try:
                        measuredPar = self.parameters['Measured']
                    except KeyError:
                        print('The measured bicycle parameters need to be ' +
                              'available, create your bicycle such that they ' +
                              'are available.')
                        raise
                    riderPar, human, bicycleRiderPar =\
                        rider.configure_rider(pathToRider, bicycleName,
                                bicyclePar, measuredPar, draw)
                else:
                    print("Loaded the precalculated parameters from " +
                          "{0}".format(pathToParFile))
                    bicycleRiderPar = inertia.combine_bike_rider(bicyclePar, riderPar)
            # set the attributes
            self.riderPar['Benchmark'] = riderPar
            try:
                self.human = human
            except NameError:
                self.human = None
            self.parameters['Benchmark'] = bicycleRiderPar
            self.riderName = riderName
            self.hasRider = True