Skip to content

Latest commit

 

History

History
605 lines (466 loc) · 26.5 KB

calculations.mdx

File metadata and controls

605 lines (466 loc) · 26.5 KB
title
Calculations

import ConventionalModelDefaults from "/snippets/defaults_conventional_model.mdx"; import PowerModelDefaults from "/snippets/defaults_power_model.mdx"; import VideoPlayerDefaults from "/snippets/defaults_video_player.mdx"; import ConsumerDeviceDefaults from "/snippets/defaults_consumer_device.mdx"; import DeviceSizeDefaults from "/snippets/defaults_device_size.mdx"; import MediaSizeDefaults from "/snippets/defaults_media_size.mdx"; import TimeInViewDefaults from "/snippets/defaults_time_in_view.mdx"; import AdPlatformDefaults from "/snippets/defaults_ad_platform.mdx"; import NetworkTrafficDefaults from "/snippets/defaults_network_traffic.mdx"; import ChannelMappingDefaults from "/snippets/defaults_channel_mapping.mdx";

Detailed walkthrough of calculations

Entity Definitions

Channels

Channel Description
web Website that is not primarily social or CTV
app Mobile app that is not primarily social or CTV
social A social platform (Snapchat, Facebook, etc)
ctv-bvod A TV-like streaming platform
streaming-video Website or app with online video content
audio Audio content (podcasts, streaming music)
dooh Digital out of home - billboards, transit, etc

Device Types

Device type Description
phone A phone
tablet A tablet
pc A pc with a monitor or a laptop
tv A TV
smart-speaker A smart speaker - Amazon Echo or equivalent

Network Types

Network type Description
mobile A mobile network (3G/4G/5G)
fixed A fixed network (broadband)

Video Player

Field Description
size_bytes Size of the javascript/html for a video player if present
buffering_seconds Video player buffering - if player preloads content, leave blank
download_trigger What starts the content download - impression, view (ie lazy load), play
Field Description
rendered_width_pixels Width of the creative when rendered. Leave blank for responsive (will assume screen width)
rendered_height_pixels Height of the creative when rendered. Leave blank for responsive (will assume screen height)
image_sizes Array of image dimensions (eg ["300x250", "70x70"])
audio_duration_seconds Audio duration (if applicable)
video_duration_seconds Video duration (if applicable)
video_player Video player used to render video (if applicable)
other_assets_bytes Metadata, text, html, etc
ad_platforms Ad serving, verification, and measurement ad platforms wrapping or embedded in the ad format

Sample Ad Formats:

300x250 programmatic banner

image_sizes = ['300x250']
rendered_width_pixels = 300,
rendered_height_pixels = 250

30 second audio inserted into a podcast

audio_duration_seconds = 30

15 second outstream video

video_duration_seconds = 15;
video_player = 'default',
rendered_width_pixels = 500,
rendered_height_pixels = 400

Native product carousel

  image_sizes = ['400x400','400x400','400x400'],
  other_assets_bytes = 7321,
  rendered_height_pixels = 600,
  rendered_width_pixels = 450

Property

Field Description
channels The channel(s) of this property
average_seconds_per_session_excluding_ads The average length of a session on this property excluding ads (eg 44 min of a 60 min TV show)
average_imps_per_session The average number of impressions per session
average_data_kb_per_session_excluding_ads The average number of KB transferred during a session excluding ads
video_bitrate_kbps The average bitrate for a CTV-BVOD property (e.g. 4200 kbps)
ad_funded_percentage 0-100 The percentage of content funded by advertising (eg 50)
allocated_adjusted_corporate_emissions_kgco2e This property's share of corporate emissions
total_sessions Number of sessions in the same time period as corporate emissions
organization_model_quality Parent organization model quality (1-5)
model_quality Model quality (1-5)

Ad Platform

Field Description
emissions_per_creative_request_per_geo_gco2_per_imp Adjusted, allocated emissions per creative request by continent (NAMER, LATAM, EMEA, JAPAC)
emissions_per_bid_request_per_geo_gco2_per_imp Adjusted, allocated emissions per bid request by continent (NAMER, LATAM, EMEA, JAPAC)
emissions_per_rtdp_request_per_geo_gco2_per_imp Adjusted, allocated emissions per rtdp request by continent (NAMER, LATAM, EMEA, JAPAC)
bidders Array of ad platforms that are sent bid requests
real_time_data_providers Array of ad platforms that are sent real-time data requests (not propagated)
distribution_rate_by_bidder_by_country Traffic shaping data for each bidder by country (eg 'xandr.com', 'US', 0.58)
average_bid_request_size Average size of a client-side bid request
sends_client_side_requests Does this platform send client-side bid requests (eg prebid client)
model_quality Model quality (1-5)

Placement

Field Description
ad_platforms The ad platforms called by this placement

Delivery Row

Field Description
impressions The number of impressions counted (required for all channels other than DOOH)
views The number of views counted
plays The number of plays (required for DOOH)
utc_datetime Date and time, in UTC, when impressions were delivered
country The country where the impression was delivered
region The region of the country where the impression was delivered
channel See channels
device_type See device types
network_type See network types
property See property
creative_ad_format Either a basic or vendor-provided ad format
creative_ad_platforms Ad serving, verification, and measurement ad platforms wrapping or embedded in the creative
creative_total_image_data_transfer_bytes Total bytes for the data transfer for the image itself for all impressions, ideally measured by the CDN
creative_image_sizes Array of image sizes included in the creative
creative_total_audio_data_transfer_bytes Total bytes for the data transfer for the core audio asset for all impressions, ideally measured by the CDN
creative_audio_duration_seconds Average audio duration in seconds for a single impression
creative_total_video_data_transfer_bytes Total bytes for the data transfer for the core video asset for all loads, ideally measured by the CDN
creative_video_vast_bytes Average size of VAST/VPAID wrapper for the video in bytes for a single load
creative_video_bitrate_kbps Video bitrate as delivered in kilobits per second
creative_video_size_bytes Average video size as delivered in bytes for a single load
creative_video_duration_seconds Video duration in seconds
creative_video_view_time_seconds Average time, in seconds, that a video is viewed
creative_video_view_rate Average percentage of a video that is viewed
creative_time_in_view_seconds Time that the creative was visible on the device
creative_is_3p_served Is the ad format served by a third party ad server

Defaults

Conventional model data transfer by network type

From SRIxAD database 2.1, original source ADEME_220830_v1.4

Power model data transfer by network type

From Carbon impact of video streaming (Carbon Trust), Table 5; and calculated here

Mobile to fixed ratios by country

From ITU Data Hub (2022 data)

Video player characteristics

Based on actual data transfer of https://vjs.zencdn.net/8.10.0/video.min.js on February 23, 2024

Media size

Based on YouTube recommendations, Wikipedia

Device size

From common devices (Quad HD 27” monitor, iPhone 13, Nexus 5X, iPad Air 1/2, iPad 2/3, Nexus 9, 1080P TV)

Device energy use and embodied emissions

See Consumer Devices

Time in view for non-video ads

Observations from various channels

Ad platform defaults

Observations from various channels

Channel and device type mappings

Lookups from external sources

Carbon intensity by country, region, and UTC Date/Time

Providers should clearly and publicly document:

  • Which data provider is used for carbon intensity data (for instance, WattTime or ElectricityMaps)
  • What carbon intensity metric is used (marginal vs average)

lookup_carbon_intensity_gco2e_per_kwh(country, region, utc_datetime) should look up the carbon intensity in gCO2e based on 100-year global warming potential (GWP100) from a database at no less than hourly granularity.

lookup_carbon_intensity_quality(country, region) should return the quality of the underlying grid mix data on a scale of 1-5 per Model Quality.

Fallbacks

We use all data we have available on every single request but in many situations we may lack some information, for this we have a series of fallbacks to be able to provide reasonable estimates in most situations.

To determine network when it's not submitted we calculate costs associated to network type as a weighted average of the fixed and mobile usage in the country (if available) or worldwide.

We can also generally determine the channel from the property or when that is ambiguous but we have device information we fall back to a default channel by device.

  pct_mobile =
      country ?
      default_percent_mobile_by_country[country] / 100 :
      default_percent_mobile / 100

  average_embodied_emissions_gco2e_per_kb =
      default_network_embodied_emissions_gco2e_per_kb['mobile'] x pct_mobile +
      default_network_embodied_emissions_gco2e_per_kb['fixed'] x (1 - pct_mobile)

  embodied_emissions_gco2e_per_kb =
      network_type ?
      default_network_embodied_emissions_gco2e_per_kb[network_type] :
      average_embodied_emissions_gco2e_per_kb

  average_usage_kwh_per_gb =
      default_usage_kwh_per_gb['mobile'] x pct_mobile +
      default_usage_kwh_per_gb['fixed'] x (1 - pct_mobile)

  usage_kwh_per_gb =
      network_type ?
      default_usage_kwh_per_gb['network_type'] :
      average_usage_kwh_per_gb

  average_baseload_watts =
      default_baseload_watts['mobile'] x pct_mobile +
      default_baseload_watts['fixed'] x (1 - pct_mobile)

  average_dynamic_watts_per_mbps =
      default_dynamic_watts_per_mbps['mobile'] x pct_mobile +
      default_dynamic_watts_per_mbps['fixed'] x (1 - pct_mobile)

  baseload_watts =
      network_type ?
      default_baseload_watts[network_type] :
      average_baseload_watts

  dynamic_watts_per_mbps =
      network_type ?
      default_dynamic_watts_per_mbps[network_type] :
      average_dynamic_watts_per_mbps

  lookup_channel:
      if property.channels.length == 1:
            return property.channels[0]
      if channel && channel in property.channels:
            return channel
      is_audio_creative =
            creative_audio_data_transfer_bytes ||
            creative_audio_duration_seconds ||
            ad_format.audio_duration_seconds
      if is_audio_creative && 'audio' in property.channels:
            return 'audio'
      if device_type && default_channel_by_device[device_type] in property.channels:
            return default_channel_by_device[device_type]
      return property.channels[0]

      channel = lookup_channel()
      device_type = device_type ? default_device_by_channel[channel]

Calculating Emissions

Creative Delivery - Data Transfer

creative_data_transfer_emissions_gco2_per_imp =
      creative_data_transfer_usage_emissions_gco2_per_imp +
      creative_data_transfer_embodied_emissions_gco2_per_imp

For all channels other than CTV/BVOD, use the conventional model:

creative_data_transfer_bytes =
      video_bytes +
      audio_bytes +
      image_bytes +
      ad_format.video_player.size_bytes +
      ad_format.other_asset_bytes

creative_data_transfer_usage_emissions_gco2 =
      creative_data_transfer_bytes / 1000 x
      usage_kwh_per_gb / 1000000 x
      lookup_carbon_intensity_gco2e_per_kwh(country, region, utc_datetime)

creative_data_transfer_embodied_emissions_gco2 =
      creative_data_transfer_bytes / 1000 x
      embodied_emissions_gco2e_per_kb

If data transfer is provided in the delivery row, use it:

image_bytes = creative_total_image_data_transfer_bytes
video_bytes = creative_total_video_data_transfer_bytes + (creative_video_vast_bytes x loads)
audio_bytes = creative_total_audio_data_transfer_bytes

Otherwise, calculate data transfer:

image_sizes = creative_image_sizes ? ad_format.image_sizes
image_bytes = SUM(image_sizes[n].width x image_sizes[n].height) x 3 / default_image_compression_ratio x impressions

audio_duration = creative_audio_duration_seconds ?? ad_format.audio_duration_seconds
audio_bytes = audio_duration_seconds x default_audio_bitrate_kbps[device_type] / 8 x 1000 x impressions

is_primary_experience = !ad_format.rendered_width_pixels && !ad_format.rendered_height_pixels
default_bitrate_kbps =
      is_primary_experience ?
      default_video_bitrate_kbps[device_type] :
      default_non_primary_video_bitrate_kbps
video_bitrate_kbps =
      creative_video_bitrate_kbps ??
      creative_video_size_bytes x 8 / 1000 / creative_video_duration  ??
      property.video_bitrate_kbps[device_type] ??
      default_bitrate_kbps
video_duration = creative_video_duration_seconds ?? ad_format.video_duration_seconds
seconds_watched = creative_video_view_time_seconds ??
                  creative_video_view_rate x video_duration_seconds ??
                  video_duration_seconds
buffer = ad_format.video_player.buffering_seconds ?? infinity
seconds_streamed = MIN(seconds_watched + buffer, video_duration_seconds)
loads = switch(ad_format.video_player.download_trigger):
            'view': views
            'play': plays
            'impression': impressions


video_bytes = (video_bitrate_kbps / 8 x 1000 x seconds_streamed + creative_video_vast_bytes) x loads

For CTV/BVOD, use the power model:

video_bitrate_kbps =
      creative_video_bitrate_kbps ??
      property.video_bitrate_kbps[device_type] ??
      default_video_bitrate_kbps[device_type]

power_watts =
      baseload_watts +
      dynamic_watts_per_mbps x video_bitrate_kbps / 1000

creative_data_transfer_usage_emissions_gco2_per_imp =
      creative_video_duration_seconds / 3600 x
      power_watts / 1000 x
      lookup_carbon_intensity_gco2e_per_kwh(country, region, utc_datetime)

creative_data_transfer_embodied_emissions_gco2_per_imp =
      creative_video_duration_seconds x
      video_bitrate_kbps / 128 x
      embodied_emissions_gco2e_per_kb

Creative Delivery - Platform

default_creative_platforms =
      creative_is_3p_served ?
      [generic_creative_ad_server, generic_measurement_platform] :
      []
creative_platforms = creative_ad_platforms ?? default_creative_platforms

creative_platform_emissions_gco2_per_imp = 0
for platform in [creative_platforms, ad_format.ad_platforms]:
      creative_platform_emissions_gco2_per_imp += platform.emissions_per_creative_request_per_geo_gco2_per_imp

Creative Delivery - Consumer Device

audio_device_coverage =
      device_type == 'smart-speaker' ? 1 : 0
audio_device_coverage_seconds =
      audio_device_coverage x
      audio_duration

device_pixels = default_device_width[device_type] x default_device_height[device_type]
rendered_width = ad_format.rendered_width_pixels ?? default_device_width[device_type]
rendered_height = ad_format.rendered_height_pixels ?? default_device_height[device_type]
visual_device_coverage =
      is_primary_experience ?
      1 :
      MIN(1, rendered_width x rendered_height / device_pixels)
time_in_view =
      video_duration ??
      creative_time_in_view_seconds ??
      default_time_in_view_seconds

device_coverage_seconds =
      audio_duration ?
      audio_device_coverage_seconds :
      visual_device_coverage x time_in_view

creative_consumer_device_usage_emissions_gco2_per_imp =
      device_coverage_seconds / 3600 x
      default_device_watts[device_type] / 1000 x
      lookup_carbon_intensity_gco2e_per_kwh(country, region, utc_datetime)

creative_consumer_device_embodied_emissions_gco2_per_imp =
      device_coverage_seconds x
      default_device_embodied_emissions_per_second[device_type]

Media Delivery - Data Transfer

media_data_transfer_emissions_gco2_per_imp =
      media_data_transfer_usage_emissions_gco2_per_imp +
      media_data_transfer_embodied_emissions_gco2_per_imp

Determing the session seconds for a single impressions

session_seconds_per_imp =
      property.average_seconds_per_session_excluding_ads x
      property.ad_funded_percentage/100 /
      property.average_imps_per_session

For all channels other than CTV/BVOD, use the conventional model:

media_data_transfer_kb_per_imp =
      property.average_data_kb_per_session_excluding_ads x
      property.ad_funded_percentage/100  /
      property.average_imps_per_session

media_data_transfer_usage_emissions_gco2_per_imp =
      media_data_transfer_kb_per_imp x
      usage_kwh_per_gb / 1000000 x
      lookup_carbon_intensity_gco2e_per_kwh(country, region, utc_datetime)

media_data_transfer_embodied_emissions_gco2_per_imp =
      media_data_transfer_kb_per_imp x
      embodied_emissions_gco2e_per_kb

For CTV/BVOD, use the power model:

video_bitrate_kbps = property.video_bitrate_kbps[device_type] ?? default_video_bitrate_kbps[device_type]

power_watts =
      baseload_watts +
      dynamic_watts_per_mbps x video_bitrate_kbps / 1000

media_data_transfer_usage_emissions_gco2_per_imp =
      session_seconds_per_imp / 3600 x
      power_watts / 1000 x
      lookup_carbon_intensity_gco2e_per_kwh(country, region, utc_datetime)

media_data_transfer_embodied_emissions_gco2_per_imp =
      session_seconds_per_imp x
      video_bitrate_kbps / 128 x
      embodied_emissions_gco2e_per_kb

Media Delivery - Consumer Device

media_consumer_device_usage_emissions_gco2_per_imp =
      session_seconds_per_imp / 3600 x
      default_device_watts[device_type] / 1000 x
      lookup_carbon_intensity_gco2e_per_kwh(country, region, utc_datetime)

media_consumer_device_embodied_emissions_gco2_per_imp =
      session_seconds_per_imp x
      default_device_embodied_emissions_per_second[device_type]

Media Delivery - Corporate

media_corporate_emissions_gco2_per_imp =
      property.allocated_adjusted_corporate_emissions_kg x 1000 /
      property.total_sessions /
      property.average_imps_per_session

Ad Selection - Platform

get_platform_emissions(ad_platform):
      direct_emissions = emissions_per_bid_request_per_geo_gco2_per_imp
      rtdp_emissions = 0
      for rtdp in ad_platform.real_time_data_providers:
            rtdp_emissions += emissions_per_rtdp_request_per_geo_gco2_per_imp
      bidder_emissions = 0
      for bidder in ad_platform.bidders:
            bidder_emissions += get_platform_emissions(bidder) x
                  ad_platform.distribution_rate_by_bidder_by_country[country, bidder] ?? 1
      return direct_emissions + rtdp_emissions + bidder_emissions

ad_selection_platform_emissions_gco2_per_imp = 0
data_transfer_bytes = 0

for platform in placement.ad_platforms:
  ad_selection_platform_emissions_gco2_per_imp += get_platform_emissions(platform)
  platform_bytes =
      platform.average_bid_request_size ??
      default_consumer_device_request_size_bytes[channel]
  data_transfer_bytes += default_consumer_device_request_size_bytes[channel]
  if platform.sends_client_side_requests:
    for bidder in platform.bidders:
      bidder_bytes =
          bidder.average_bid_request_size ??
          default_consumer_device_request_size_bytes[channel]
      data_transfer_bytes +=
          bidder_bytes x
          platform.distribution_rate_by_bidder_by_country[country, bidder] ?? 1

Ad Selection - Data Transfer

ad_selection_data_transfer_usage_emissions_gco2_per_imp =
      data_transfer_bytes / 1000 x
      usage_kwh_per_gb / 1000000 x
      lookup_carbon_intensity_gco2e_per_kwh(country, region, utc_datetime)

ad_selection_data_transfer_embodied_emissions_gco2_per_imp =
      data_transfer_bytes / 1000 x
      embodied_emissions_gco2e_per_kb

ad_selection_data_transfer_emissions_gco2_per_imp =
      ad_selection_data_transfer_usage_emissions_gco2_per_imp +
      ad_selection_data_transfer_embodied_emissions_gco2_per_imp

Model Quality

grid_mix_model_quality = lookup_carbon_intensity_quality(country, region)
organization_model_quality = property.organization_model_quality
property_model_quality = property.model_quality

total_platforms = 0
modeled_platforms = 0
for platform in placement.ad_platforms:
  total_platforms++
  if platform.model_quality > 1
    modeled_platforms++
  # Model one level of downstream platforms
  for bidder in ad_platform.bidders:
    total_platforms++
    if bidder.model_quality > 1
      modeled_platforms++
ad_platform_modeled_ratio = modeled_platforms / total_platforms