1. Decide on an averaging period and exponential boost.

    I used 30 seconds and 4 for mine, the same as prescribed by the Coggan formula. I left these as parameters because I think we're fast approaching a time when they can be tailored to individuals.


  2. Calculate a SMA for watts based on the averaging period in step 1

    The SMo2 recorded for any given second pretty obviously results from effort incurred prior to that second. To that end, this formula still makes use of watts averaging. Both the Coggan & Skiba formulas involve an averaging period to account for the body's reaction to the physiologic stress of a ride, although they disagree as to averaging method and averaging period.


    The averaging method doesn't seem to make too much difference overall in terms of deriving weighted average power (the exponentially weighted moving average (EMA) will be a a watt or 2 less). However the EMA calculation does involve significantly more memory and processor time so I decided to use a simple moving average (SMA) for this for now. If it ends up being more technically correct to weight the more recent seconds more then the earlier, I'm working on a less memory/processor intensive method then EMA.


    Changing the averaging period from 30 to 25 seconds resulted in as much as a 5 watt gain to the SMA for my rides. As a user of the formula I like this because it would make the rides seem tougher! For my own usage though I decided to make the averaging period 30 seconds because this period results in a better correlation to Sm02. For the implementation into the KOM Informatics system I made averaging period a parameter. What if an optimal choice ends up being dependent on an individual's physiology?


  3. Calculate the earliest point in the ride where the average SmO2 is attained

    After looking at a bunch of ride graphs I realized that warmup periods for me are characterized by an association between low SmO2 values and low Watts. My instinct here is that not a lot of fitness building work is occurring in this stage of the ride and that including this data in the later stages of this might unfairly dilute the results.

  4. Calculate average SMA watts per SMo2 Level

    The formula figures out the worth of a change in SMo2 Level in terms of SMA watts. The first step is to calculate the average SMA watts per SMo2 Level for all of those seconds in the ride where the seconds > WarmupSecond. If the results are returned in SMo2 ascending order then for most of my rides it's pretty easy to see the pattern of higher SMA watts associated with lower SMo2 levels.

  5. Calculate difference in SMA watts for contiguous SMo2 levels (AvgSMAWattsPerSMo2LevelDiff)

    The next step in the formula is to calculate the difference in average SMA watts for contiguous SMo2 levels. This step should be operating on the results returned from step 3 above.


    First calculate the CountToAverage.


    For example assume that the lowest SMo2 level in your ride is 65.5 and your second lowest is 65.6. CountToAverage would work out to (65.6 - 65.5) * 10 or 1


    Another example that skips levels: assume that the lowest SMo2 level in your ride is 65.5 and your second lowest is 65.7. CountToAverage would work out to (65.7 - 65.5) * 10 or 2


    For my data 95% + of the time CountToAverage works out to 1.0. For those times when it doesn't CountToAverage allows a little more weight to those rows.


    Next calculate the average watts associated with the difference in SMo2 levels (AvgSMAWattsPerSMo2LevelDiff) For example assume that the lowest SMo2 Level in your ride is 65.5 and your second lowest is 65.6. Subtract the AvgSMAWatts (250 AvgSMAWatts) associated with the lowest SMo2 Level from the AvgSMAWatts associated with the second lowest SMo2 Level (240 SMAWatts). The AvgSMAWattsPerSMo2LevelDiff for this row would be -10


    Do the same calculations for each set of contiguous SMo2 Levels. The results of each calculation are stored in the AvgSMAWattsPerSMo2LevelDiff column. If you ride like me, then for most rides, and especially interval rides you will generally see a drop in AvgSMAWattsPerSMo2LevelDiff as SMo2 ascends. However, the drop won't be steady, and for some of the contiguous pairs there will be a gain instead of a drop.


  6. Calculate the average AvgSMAWattsPerSMo2LevelDiff for the entire ride


    In step 4 we calculated the AvgSMAWattsPerSMo2LevelDiff for each set of contiguous SmO2 levels. In this step we derive an average of all of them.


    This number is what the a change in SMo2 Level is worth in watts, on average, for the ride. For 92% of my rides, this is a negative number. The higher watts are associated with lower SMo2 Levels. It's easy to see this in real time using the Humon Hex app or watching the SMo2 readings drop on the ELEMNT while doing intervals.


    For 8% of my rides (endurance involving mostly zone 2 efforts), this number is positive meaning that higher watts are associated with higher SMo2 Levels. The problem we're trying to solve - where a formula doesn't do full justice to rides that involve high intensity efforts - isn't occurring here. Higher watts are not resulting in lower SmO2 levels and presumably the increased lactate associated with those lower levels. Therefore we won't assign a positive watts adjustment at all for this type of ride. It'll be a negative adjustment based on how close the recorded SmO2 is to the minimum SmO2. The closer it is, the smaller the adjustment.


    Assuming you've got data in 2 columns (AvgSMAWattsPerSMo2LevelDiff and CountToAverage) the formula for this step is: SUM(AvgSMAWattsPerSMo2GradeDiff)/SUM(CountToAverage)


  7. Calculate the average SMo2 for the ride

    The average SMo2 for the ride will be used in the next step as a tipping point to decide whether to apply a positive or negative SMo2 based watts differential in the next step. This is based on the entire ride.



  8. Calculate the SMo2WattsDifferential & SMo2AdjustedWatts for the ride

    Next, the formula calculates the SMo2WattsDifferential & SMo2AdjustedWatts for the ride. The SMo2WattsDifferential is the number of watts that we'll be adding to or subtacting from the recorded watts of a ride on a second-by-second basis. Based on the SmO2 data it is supposed to account for the physiologic stress of the ride on the body. The SmO2AdjustedWatts for an individual second of a ride is that second's recorded watts plus the SMo2WattsDifferential for that second.


    First, evaluate the overall AvgSMAWattsPerSMo2LevelDiff from step 5. When AvgSMAWattsPerSMo2LevelDiff <= 0 then this is a harder ride where as SMo2 increases, watts decrease. If this is the case for the ride then For each second of the ride, evaluate whether recorded SMo2 <= AvgSMo2 for that second.
    Harder Ride (AvgSMAWattsPerSMo2LevelDiff <= 0)
    Recorded SMo2 <= AvgSMo2 for second If it is then we want to apply a positive SMo2WattsAdjustment as a lower then average SMo2 generally means we're working harder. Take the absolute value of the AvgSMAWattsPerSMo2LevelDiff and multiply that by the AvgSMo2 - SMo2. The second term just evaluates how far from the average the SMo2 for the current second is. The further away from average, the lower the SMo2, the greater the multiplier effect. (ABS(AvgSMAWattsPerSMo2LevelDiff) * (AvgSMo2 - SMo2)) is the SMo2WattsAdjustment for the second. To get the SMo2AdjustedWatts for the second, just add the raw watts value for the second.
    Recorded SMo2 > AvgSMo2 for second If SMo2 > AvgSMo2 we want to apply a negative SMo2WattsAdjustment as a higher then average SMo2 generally means we aren't working as hard. Take the AvgSMAWattsPerSMo2LevelDiff and multiply that by the SMo2 - AvgSMo2. The second term just evaluates how far from the average the SMo2 for the current second is. The further away from average, the higher the SMo2, the greater the multiplier effect. (AvgSMAWattsPerSMo2LevelDiff * (SMo2 - AvgSMo2)) is the SMo2WattsAdjustment for the second. To get the SMo2AdjustedWatts for the second, just add the raw watts value for the second.
    Easier Ride (AvgSMAWattsPerSMo2LevelDiff > 0)
    Endurance ride where as SMo2 increases watts increase. This case is happening for me about 8% of the time. The problem we're trying to solve - where a formula doesn't do full justice to rides that involve high intensity efforts - isn't occurring here. Higher watts are not resulting in lower SmO2 levels and presumably the increased lactate associated with those lower levels. Therefore we won't assign a positive watts adjustment at all for this type of ride. It'll be a negative adjustment based on how close the recorded SmO2 is to the minimum SmO2. The closer it is, the smaller the adjustment. 1. SMo2AdjustedWatts = Watts - (AvgSMAWattsPerSMo2LevelDiff * (SMo2 - MinSMo2)) for this case. The watts adjustment is (AvgSMAWattsPerSMo2LevelDiff * (SMo2 - MinSMo2))

  9. Weight the higher watts using the exponential boost from step 1 and derive the SMo2 Adjusted Weighted Average Power

    Both the Coggan and Skiba formulas use a "power dependent intensity weighting factor derived directly from a plot of blood lactate concentration as a percentage of concentration at threshold against % of threshold power. His [Coggan's] work indicated a near 4th power relationship between the two." This formula continues to use this insight. I made the power dependent intensity weighting factor a parameter. If it ends up being there are individual differences the code will adapt automatically. The steps to attain this are:


    1. For rows in which the SMo2AdjustedWatts >= 0: Raise the SMo2AdjustedWatts for each second to the @PowerWeightingFactor power
    2. For rows in which the SMo2AdjustedWatts < 0: Raise the SMo2AdjustedWatts for each second to the @PowerWeightingFactor power, then subtract this number from 0
    3. Calculate the average of the values in steps 1,2
    4. Calculate the @PowerWeightingFactor root on the number from step 2.

    The SMo2WeightedAveragePower for the ride is the number from step 3

For a T-SQL script that implements the above steps click here