content: """
  Tools to process TCX files,
  specifically for parsing and
  converting to other formats.
  """
  
  import numpy as np
  import pandas as pd
  from lxml import objectify
  import dateutil.parser
  import logging
  
  TPXNS = "{http://www.garmin.com/xmlschemas/ActivityExtension/v2}TPX"
  LXNS = "{http://www.garmin.com/xmlschemas/ActivityExtension/v2}LX"
  
  
  class TCXPandas(object):
      """
      Class for Parsing .TCX files to Pandas DataFrames.
  
      Parameters
      ----------
      tcx_file : string, path object,
                 the path to the tcx file
  
      """
  
      def __init__(self, tcx_file, **kwds):
          self.__filehandle__ = tcx_file
          self.tcx = None
          self.activity = None
          self.dataframe = None
  
          logging.basicConfig(filename="TCXconversion.log", level=logging.DEBUG)
  
      def parse(self):
          """
          Parse specified TCX file into a DataFrame
          Return a Dataframe and sets Dataframe and sets
          the self.dataframe object in the TCXParser.
          """
  
          self.tcx = objectify.parse(open(self.__filehandle__))
          self.activity = self.tcx.getroot().Activities.Activity
          self.dataframe = pd.DataFrame(self._traverse_laps_())
          return self.dataframe
  
      def get_activity_timestamp(self):
          """
          Returns the TCX file timestamp if parsed
          """
          if self.activity is None:
              return None
          else:
              return self.activity.Id
  
      def get_sport(self):
          """
          Returns the specified sport of the TCX file
          """
          if self.activity is None:
              return None
          else:
              return self.activity.attrib['Sport']
  
      def get_workout_startime(self):
          """
          Returns the starting timestamp of the specified TCX file
          """
          if self.activity is None:
              return None
          else:
              return self.activity.Lap.items()[0][1]
  
      def _traverse_laps_(self):
  
          # New iterator method to align with lxml standard
          return_array = []
          for laps in self.activity.Lap:
              for tracks in laps.Track:
                  for trackingpoints in tracks.Trackpoint:
                      return_dict = {}
                      return_dict['time'] = dateutil.parser.parse(str(trackingpoints.Time))
  
                      try:
                          return_dict['latitude'] = \
                              np.float(trackingpoints.Position.LatitudeDegrees)
                      except AttributeError:
                          pass #TODO log this
  
                      try:
                          return_dict['longitude'] = \
                              np.float(trackingpoints.Position.LongitudeDegrees)
                      except AttributeError:
                          pass #TODO log this
  
                      try:
                          return_dict['altitude'] = np.float(trackingpoints.AltitudeMeters)
                      except AttributeError:
                          pass #TODO log this
  
                      try:
                          return_dict['distance'] = np.float(trackingpoints.DistanceMeters)
                      except AttributeError:
                          pass #TODO log this
  
                      try:
                          return_dict['hr'] = np.float(trackingpoints.HeartRateBpm.Value)
                      except AttributeError:
                          pass #TODO log this
  
                      try:
                          return_dict['speed'] = \
                              np.float(trackingpoints.Extensions[TPXNS].Speed)
                      except AttributeError:
                          pass #TODO log this
  
                      if self.get_sport == 'Running':
                          try:
                              return_dict['cadence'] = \
                                  np.float(trackingpoints.Extensions[TPXNS].RunCadence)
                          except AttributeError:
                              pass #TODO log this
                      else: # self.activity.attrib['Sport'] == 'Biking':
                          try:
                              return_dict['cadence'] = np.float(trackingpoints.Cadence)
                          except AttributeError:
                              pass #TODO log this
  
                          try:
                              return_dict['power'] = \
                                  np.float(trackingpoints.Extensions[TPXNS].Watts)
                          except AttributeError:
                              pass #TODO log this
  
                      return_array.append(return_dict)
                  return return_array
  