Tracing

In addition to the completely flexible callback data storage system, PassengerSim also includes the ability to “trace” certain details of the simulation. Traces are more aggregate than other callbacks, as they will follow the average values of various measures over many samples. Unlike other aggregate measures, they allow for the selection of a limited number of micro-level details, e.g. path forecasts for specific paths, or bid prices on specific legs. This contrasts with the database functionality, which can (relatively) efficiently store this information for all paths or legs. Tracing allows the analyst to probe a simulation for details of interest without becoming bogged down in the recording and storage of massive amounts of data that really isn’t needed.

import passengersim as pax

pax.versions()
passengersim 0.93
passengersim.core 0.93

Here, we’ll run a quick demo using the “3MKT” example model. We’ll give AL1 the ‘P’ RM system to make it interesting.

cfg = pax.Config.from_yaml(pax.demo_network("3MKT"))

cfg.simulation_controls.num_samples = 400
cfg.simulation_controls.burn_samples = 50
cfg.simulation_controls.num_trials = 1
cfg.db = None
cfg.outputs.reports.clear()
cfg.outputs._write_no_files()

cfg.carriers.AL1.rm_system = "P"

sim = pax.Simulation(cfg)
/Users/jpn/Git/pax/packages/passengersim-public/src/passengersim/config/manipulate.py:49: UserWarning: Only 350 usable samples remain after burning 50 of 400 samples across 1 trials; at least 750 usable samples are recommended to ensure meaningful results.
  schema_validator.validate_python(model.__dict__)

Forecast Tracing

The path forecast tracing capabilities allows us to record detailed data about a subset of Simulation path forecasts, so we can review them after the simulation. The tracing will summarize the average forecasts for the specific paths, but will not store the sample-by-sample forecast details, which would be an enormous amount of detail that will require large amounts of memory or disk storage and may not be sufficiently useful for analysis. A similar tracing tool is available for leg forecasts as well.

from passengersim.tracers.forecasts import (
    PathForecastTracer,
    fig_path_forecast_dashboard,
)

f_tracer = PathForecastTracer(path_ids=[1, 5, 9])
f_tracer.attach(sim)

Bid Price Tracing

The native summary covering every leg is enabled by default.

After running, access summary.leg_bid_price_history. It is indexed by (leg_id, days_prior) and contains:

Column

Meaning

bid_price_mean

Mean bid price across retained samples and trials

bid_price_std_dev

Pooled sample standard deviation

n_observations

Number of retained observations for that leg and day

summary = pax.Simulation(cfg).run()
daily_prices = summary.leg_bid_price_history
one_leg = daily_prices.xs(101, level="leg_id")

Collection includes each integer day from the earliest configured DCP through departure day, excludes burn-in, and works with cfg.db = None. It is on by default; the table is None when collection is disabled. Set collect_leg_bid_prices: false before the next run to turn it off. The option always collects all legs; filtering the resulting table does not reduce collection. A cell with no observations has a missing mean and standard deviation; a single observation has a missing standard deviation. The native collector stores online statistics rather than individual sample observations, and saved PXSIM and pickle results retain the information needed to combine summaries correctly.

Native collection follows core daily-statistics timing and the existing leg reporting-price convention, including sold-out legs. For positive days_prior, recording occurs at the core daily or DCP event; later callbacks can subsequently change prices. At days_prior == 0, recording occurs at the end of the sample, after the event queue finishes. The native collector has no callback priority setting, so a Python tracer may observe different prices if callbacks change them between these times. Multi-cabin legs record their leg-level reporting price without selecting a cabin or applying cabin capacity-sharing rules.

Each row pools individual observations across retained samples, trials, and workers. The standard deviation is the sample standard deviation of those observations (ddof=1), including variation between trials. It is not the average of trial standard deviations. Rerunning a simulation starts a fresh history; saved summaries retain their previous results. This table requires no database report selection.

You can use native collection alongside LegBidPriceTracer. Use the Python tracer below when selecting only some legs or developing custom collection behavior. Its existing aggregation behavior is unchanged. Cabin-level collection is not yet enabled by this option.

Selected legs and paths

Similarly, the bid price tracing feature allows us to record detailed data about a subset of Simulation bid prices. We can record bid prices by leg, path, or both if desired. Each tracer only attaches to the bid prices on a selected subset of individual legs, so as to not overwhelm the simulation with data.

from passengersim.tracers.bid_price import (
    LegBidPriceTracer,
    PathBidPriceTracer,
    fig_leg_bid_prices,
    fig_path_bid_prices,
)

bp_tracer = PathBidPriceTracer(path_ids=[1, 5, 9])
bp_tracer.attach(sim)

leg_bp_tracer = LegBidPriceTracer(leg_ids=[101, 111])
leg_bp_tracer.attach(sim)

Once the tracers have been attached, we run the simulation as normal. The attached tracers will automatically collect and aggregate the relevant data, and attach the tabulated results to the summary outputs.

summary = sim.run()

Task Completed after 4.03 seconds

All the usual summary data remains available for review and analysis.

summary.fig_carrier_revenues()
summary.fig_fare_class_mix()

Dashboards

In addition to the usual summary reports, the output summary also provides the data needed to power detailed dashboard visualizations for each of the traced paths or legs.

For the selected paths or legs, we can review a forecast dashboard that shows the forecast mean and std dev for each fare class from each DCP through departure, the mean forecast within each timeframe, as well as history data on yieldable and (if recorded separately) priceable sales, and average closure rates at each DCP. The displayed data in each dashboard is specific to the selected path or leg, but averaged across all relevant (non-burned) samples in the simulation.

fig_path_forecast_dashboard(summary, path_id=1)
fig_path_forecast_dashboard(summary, path_id=5)

The dashboards for bid price tracing are less busy than those for the forecasts, as the bid price

fig_path_bid_prices(summary)
fig_leg_bid_prices(summary)

Tracers in Callback Data

All the underlying data for these reports is stored in the summary’s callback_data attribute, if you want to access it to parse or visualize it differently. The forecast tracers contain selected summary statistics by path or leg, days prior, and fare class. These statistics are aggregated across all relevant (i.e. non-burned) samples.

summary.callback_data.selected_path_forecasts
mean_to_departure stdev_to_departure ... history_sold_yieldable history_closure
booking_class Y0 Y1 Y2 Y3 Y4 Y5 Y0 Y1 Y2 Y3 ... Y2 Y3 Y4 Y5 Y0 Y1 Y2 Y3 Y4 Y5
path_id days_prior
1 63 2.519225 10.374047 5.623006 1.820497 12.098788 6.376606 1.841788 4.199357 2.979923 1.669202 ... 0.323956 0.087143 2.390330 1.441209 0.000000 0.000000 0.000000 0.000000 0.000000 0.023846
56 2.370873 9.799542 5.299050 1.733354 9.708458 4.908230 1.765909 4.027200 2.868659 1.632516 ... 0.280330 0.026593 1.100110 0.634615 0.000000 0.000000 0.000000 0.000000 0.000000 0.055275
49 2.256367 9.348113 5.018720 1.706760 8.608348 4.229857 1.712005 3.863264 2.773465 1.621698 ... 0.236813 0.059560 1.324176 0.754066 0.000000 0.000000 0.000000 0.000000 0.000000 0.096484
42 2.159994 8.909212 4.781907 1.647200 7.284172 3.379610 1.655283 3.681610 2.693027 1.597512 ... 0.267473 0.051099 1.310330 0.731648 0.000000 0.000000 0.000000 0.000000 0.015275 0.130659
35 2.035598 8.413607 4.514435 1.596101 5.958892 2.520796 1.611306 3.564171 2.616940 1.549927 ... 0.195824 0.014505 0.835055 0.403736 0.000000 0.000000 0.000000 0.000000 0.032088 0.157473
31 1.952741 8.173607 4.318610 1.581596 5.093382 2.014558 1.603589 3.520386 2.540156 1.528579 ... 0.097143 0.019560 0.534396 0.297692 0.000000 0.000000 0.000000 0.000000 0.046703 0.174176
28 1.899994 7.973937 4.221468 1.562035 4.523987 1.597473 1.586357 3.480361 2.499054 1.526228 ... 0.184945 0.040000 1.174725 0.620110 0.000000 0.000000 0.000000 0.000000 0.069121 0.192637
24 1.844609 7.698882 4.036523 1.522035 3.258517 0.777205 1.560270 3.417843 2.389897 1.498067 ... 0.166813 0.061429 1.131099 0.605165 0.000000 0.000000 0.000000 0.026374 0.112527 0.197692
21 1.792631 7.372289 3.869709 1.443080 1.990836 0.000000 1.550078 3.296036 2.315196 1.334705 ... 0.246484 0.105055 0.947473 0.000000 0.000000 0.000000 0.005275 0.061648 0.132967 1.000000
17 1.726477 7.006904 3.618751 1.304212 0.865457 0.000000 1.530168 3.192887 2.182090 1.152873 ... 0.309890 0.062527 0.718571 0.000000 0.000000 0.000000 0.027143 0.083846 0.138681 1.000000
14 1.589334 6.547673 3.295915 1.213890 0.000000 0.000000 1.468984 2.984176 2.053184 1.047648 ... 0.706264 0.646484 0.000000 0.000000 0.000000 0.005714 0.054286 0.123846 1.000000 1.000000
10 1.401312 5.595162 2.532047 0.458235 0.000000 0.000000 1.398729 2.770857 1.681853 0.576409 ... 0.685165 0.353077 0.000000 0.000000 0.002857 0.017033 0.111099 0.172637 1.000000 1.000000
7 1.151694 4.353370 1.746950 0.000000 0.000000 0.000000 1.253405 2.359734 1.281018 0.000000 ... 0.610110 0.000000 0.000000 0.000000 0.011429 0.040110 0.147253 1.000000 1.000000 1.000000
5 0.978151 3.647657 1.008678 0.000000 0.000000 0.000000 1.084364 2.050445 0.978393 0.000000 ... 0.795495 0.000000 0.000000 0.000000 0.025714 0.072967 0.187253 1.000000 1.000000 1.000000
3 0.784203 2.767603 0.000000 0.000000 0.000000 0.000000 0.954902 1.692260 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.161538 0.192198 1.000000 1.000000 1.000000 1.000000
1 0.184503 0.683981 0.000000 0.000000 0.000000 0.000000 0.342088 0.739791 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.235824 0.262637 1.000000 1.000000 1.000000 1.000000
5 63 15.786047 11.539045 4.393738 3.706642 24.698673 7.014791 5.993350 4.657413 2.667416 3.656797 ... 0.223187 0.049670 4.796264 0.643956 0.000000 0.000000 0.000000 0.000000 0.054066 0.605495
56 14.870003 10.940364 4.170552 3.656972 19.706385 5.797616 5.686949 4.480117 2.581025 3.628634 ... 0.180000 0.021538 2.245495 0.301538 0.000000 0.000000 0.000000 0.000000 0.063407 0.568352
49 14.147696 10.390254 3.990552 3.635433 17.362686 5.071966 5.476290 4.285314 2.509674 3.629903 ... 0.161099 0.020000 2.377582 0.427363 0.000000 0.000000 0.000000 0.000000 0.121648 0.595934
42 13.463960 10.002891 3.829453 3.615433 14.759889 4.044749 5.244184 4.155474 2.455921 3.620889 ... 0.146484 0.038791 2.426044 0.349451 0.000000 0.000000 0.000000 0.000000 0.159121 0.625714
35 12.691981 9.497177 3.682969 3.576642 11.987202 3.123935 4.991413 3.960937 2.363217 3.594884 ... 0.114176 0.068791 1.619341 0.282637 0.000000 0.000000 0.000000 0.000000 0.192747 0.581758
31 12.285498 9.188386 3.568793 3.507851 10.066088 2.337862 4.857318 3.854015 2.304824 3.481959 ... 0.076374 0.103736 1.045604 0.175824 0.000000 0.000000 0.000000 0.000000 0.203297 0.539011
28 12.003080 8.961023 3.492420 3.404115 8.759457 1.911655 4.796003 3.765904 2.264356 3.269522 ... 0.089451 0.245055 2.009670 0.424505 0.000000 0.000000 0.000000 0.016593 0.261648 0.546593
24 11.555058 8.640034 3.402969 3.089363 6.212109 0.927593 4.648812 3.667460 2.186910 2.670570 ... 0.109670 0.404725 1.685385 0.416374 0.000000 0.000000 0.005714 0.059890 0.321648 0.512308
21 11.116487 8.323221 3.291534 2.623056 3.931719 0.000000 4.526608 3.588079 2.126784 2.008227 ... 0.179890 0.341429 1.481538 0.000000 0.000000 0.000000 0.016593 0.102418 0.346593 1.000000
17 10.492201 7.858935 3.097731 2.202237 1.811265 0.000000 4.350876 3.462627 1.969714 1.522496 ... 0.255055 0.218791 1.189341 0.000000 0.000000 0.000000 0.048022 0.207912 0.361758 1.000000
14 9.773520 7.369704 2.811396 1.858348 0.000000 0.000000 4.130628 3.284476 1.758963 1.215350 ... 0.473516 0.750989 0.000000 0.000000 0.000000 0.005714 0.107033 0.283077 1.000000 1.000000
10 8.197696 6.252338 2.261889 0.784495 0.000000 0.000000 3.749641 2.888658 1.458371 0.735226 ... 0.500879 0.484396 0.000000 0.000000 0.000000 0.047692 0.198571 0.324945 1.000000 1.000000
7 6.356267 4.899263 1.600629 0.000000 0.000000 0.000000 2.992816 2.360489 1.142229 0.000000 ... 0.432198 0.000000 0.000000 0.000000 0.002857 0.089670 0.253736 1.000000 1.000000 1.000000
5 5.052391 4.009888 0.955578 0.000000 0.000000 0.000000 2.529070 2.046100 0.808495 0.000000 ... 0.655714 0.000000 0.000000 0.000000 0.031429 0.168022 0.277363 1.000000 1.000000 1.000000
3 3.824248 3.127389 0.000000 0.000000 0.000000 0.000000 2.061337 1.743117 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.192747 0.280659 1.000000 1.000000 1.000000 1.000000
1 0.993626 0.929431 0.000000 0.000000 0.000000 0.000000 0.883903 0.805394 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.350769 0.368681 1.000000 1.000000 1.000000 1.000000
9 63 11.239237 7.122344 6.350948 3.861208 21.076203 10.489861 4.548650 3.622967 3.133540 3.363107 ... 0.324725 0.086813 3.693516 0.852088 0.000000 0.000000 0.000000 0.000000 0.000000 0.666044
56 10.590116 6.732894 6.026223 3.774395 17.382687 8.875458 4.423472 3.498516 3.078838 3.323460 ... 0.220769 0.045714 1.880330 0.491429 0.000000 0.000000 0.000000 0.000000 0.000000 0.599231
49 10.073523 6.434322 5.805453 3.728681 15.502357 7.733590 4.280725 3.372427 3.002988 3.339195 ... 0.231099 0.049890 2.239121 0.633516 0.000000 0.000000 0.000000 0.000000 0.000000 0.546154
42 9.664732 6.189817 5.574354 3.678791 13.263236 6.348019 4.161041 3.273644 2.922373 3.325657 ... 0.242308 0.082088 2.207363 0.728901 0.000000 0.000000 0.000000 0.000000 0.022418 0.513407
35 9.174951 5.931575 5.332047 3.596703 11.018095 4.868853 4.008794 3.181218 2.849479 3.325421 ... 0.146703 0.042857 1.365824 0.462637 0.000000 0.000000 0.000000 0.000000 0.050989 0.496374
31 8.830776 5.748278 5.185343 3.553846 9.583276 3.882217 3.907022 3.163236 2.804876 3.291610 ... 0.111868 0.073077 1.037033 0.391209 0.000000 0.000000 0.000000 0.000000 0.062967 0.454286
28 8.615501 5.614762 5.073475 3.480769 8.471610 3.104990 3.861518 3.116044 2.770166 3.176095 ... 0.164835 0.204835 1.996484 0.857033 0.000000 0.000000 0.000000 0.005714 0.126374 0.456154
24 8.362754 5.447289 4.908640 3.263717 6.219226 1.536591 3.780630 3.052886 2.698428 2.844689 ... 0.171868 0.343516 1.826484 0.827143 0.000000 0.000000 0.000000 0.016813 0.171538 0.435495
21 8.053413 5.276190 4.736772 2.903867 4.030479 0.000000 3.699657 2.956515 2.628776 2.285589 ... 0.253736 0.345714 1.744505 0.000000 0.000000 0.000000 0.000000 0.080110 0.223077 1.000000
17 7.615061 5.011465 4.483036 2.490465 1.814114 0.000000 3.546689 2.873885 2.527601 1.816806 ... 0.332418 0.293297 1.316484 0.000000 0.000000 0.000000 0.002857 0.125385 0.280220 1.000000
14 7.020556 4.665641 4.149567 2.111309 0.000000 0.000000 3.350531 2.743552 2.417359 1.479005 ... 0.820769 0.974725 0.000000 0.000000 0.000000 0.000000 0.026154 0.184176 1.000000 1.000000
10 6.007809 4.036520 3.305379 0.915746 0.000000 0.000000 2.904390 2.471129 1.986225 0.832167 ... 0.855275 0.627692 0.000000 0.000000 0.000000 0.000000 0.097582 0.278022 1.000000 1.000000
7 4.786380 3.360806 2.342091 0.000000 0.000000 0.000000 2.444259 2.086576 1.542193 0.000000 ... 0.774286 0.000000 0.000000 0.000000 0.000000 0.011429 0.127253 1.000000 1.000000 1.000000
5 3.981105 2.885407 1.437357 0.000000 0.000000 0.000000 2.121943 1.801816 1.173575 0.000000 ... 1.147253 0.000000 0.000000 0.000000 0.011429 0.058681 0.200110 1.000000 1.000000 1.000000
3 3.075430 2.231383 0.000000 0.000000 0.000000 0.000000 1.816098 1.451841 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.245604 0.248462 1.000000 1.000000 1.000000 1.000000
1 0.783020 0.631058 0.000000 0.000000 0.000000 0.000000 0.662269 0.633976 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.389231 0.392088 1.000000 1.000000 1.000000 1.000000

48 rows × 36 columns

The bid prices data includes the mean and standard deviation of the leg or path bid price, by days prior.

summary.callback_data.leg_bid_prices
leg_id 101 111
statistic days_prior
mean 63 57.459262 138.760143
62 56.579301 139.420068
61 56.454774 138.863349
60 57.490988 138.370916
59 57.564248 138.214815
... ... ... ...
std_dev 4 103.037045 162.837045
3 118.738710 173.073231
2 139.654349 191.723921
1 162.908657 208.535773
0 185.649037 236.518637

128 rows × 2 columns

Relationship to Callbacks

Unlike other callback data, the tracers are not stored by sample day, as that would generally create an overwhelming amount of data to store, and we are typically not interested in that much detail. If we are interested in grabbing and storing path forecast data for individual sample days, we can still do that with the regular callback interface.

sim1 = pax.Simulation(cfg)
/Users/jpn/Git/pax/packages/passengersim-public/src/passengersim/config/manipulate.py:49: UserWarning: Only 350 usable samples remain after burning 50 of 400 samples across 1 trials; at least 750 usable samples are recommended to ensure meaningful results.
  schema_validator.validate_python(model.__dict__)
@sim1.begin_sample_callback
def grab_forecasts(sim):
    if sim.eng.sample not in [300, 375]:
        return
    return {
        f"path-{p}": sim.eng.paths.select(path_id=p).get_forecast_data()
        for p in [1, 5, 9]
    }
summary1 = sim1.run()

Task Completed after 2.81 seconds

When run like this, we capture not the average path forecast over the simulation, but rather the exact path forecast for the selected paths (1 and 9) at sample days 300 and 375. The data is stored in the callback_data.begin_sample attribute:

summary1.callback_data.begin_sample
[{'trial': 0,
  'sample': 300,
  'path-1': <passengersim_core.forecast_tools.ForecastData at 0x1233af260>,
  'path-5': <passengersim_core.forecast_tools.ForecastData at 0x1235d5400>,
  'path-9': <passengersim_core.forecast_tools.ForecastData at 0x123675d60>},
 {'trial': 0,
  'sample': 375,
  'path-1': <passengersim_core.forecast_tools.ForecastData at 0x123688530>,
  'path-5': <passengersim_core.forecast_tools.ForecastData at 0x123688a70>,
  'path-9': <passengersim_core.forecast_tools.ForecastData at 0x1236ade80>}]

We can review the details of each specific forecast by accessing the dashboard visualization.

summary1.callback_data.begin_sample[0]["path-1"].dashboard()

We can also access individual sub-tables of forecast data as pandas DataFrames, to manipulate or visualize as we like.

summary1.callback_data.begin_sample[0]["path-1"].history_sold_yieldable
booking_class Y0 Y1 Y2 Y3 Y4 Y5
tf_index
0 0.115385 0.692308 0.346154 0.269231 1.923077 1.307692
1 0.115385 0.423077 0.346154 0.038462 1.115385 0.576923
2 0.115385 0.538462 0.461538 0.153846 1.000000 0.692308
3 0.076923 0.461538 0.076923 0.153846 1.423077 0.692308
4 0.192308 0.269231 0.153846 0.000000 0.461538 0.653846
5 0.115385 0.269231 0.153846 0.038462 0.461538 0.346154
6 0.038462 0.230769 0.192308 0.038462 1.269231 0.500000
7 0.000000 0.346154 0.153846 0.038462 1.615385 0.615385
8 0.000000 0.615385 0.230769 0.038462 0.807692 0.000000
9 0.038462 0.538462 0.384615 0.076923 0.615385 0.000000
10 0.153846 1.192308 1.000000 0.538462 0.000000 0.000000
11 0.307692 1.230769 0.769231 0.461538 0.000000 0.000000
12 0.153846 0.653846 0.692308 0.000000 0.000000 0.000000
13 0.230769 0.807692 1.000000 0.000000 0.000000 0.000000
14 0.423077 1.653846 0.000000 0.000000 0.000000 0.000000
15 0.115385 0.307692 0.000000 0.000000 0.000000 0.000000
summary1.callback_data.begin_sample[0]["path-1"].mean_in_timeframe
booking_class Y0 Y1 Y2 Y3 Y4 Y5
tf_index
0 0.115385 0.692308 0.346154 0.269231 1.923077 1.371344
1 0.115385 0.423077 0.346154 0.038462 1.115385 0.610897
2 0.115385 0.538462 0.461538 0.153846 1.000000 0.732365
3 0.076923 0.461538 0.076923 0.153846 1.423077 0.768233
4 0.192308 0.269231 0.153846 0.000000 0.461538 0.722510
5 0.115385 0.269231 0.153846 0.038462 0.489893 0.425546
6 0.038462 0.230769 0.192308 0.038462 1.402789 0.605596
7 0.000000 0.346154 0.153846 0.038462 1.796260 0.779815
8 0.000000 0.615385 0.230769 0.045216 1.024889 0.000000
9 0.038462 0.538462 0.384615 0.202084 0.761815 0.000000
10 0.153846 1.192308 1.000000 0.621449 0.000000 0.000000
11 0.307692 1.230769 0.832424 0.562259 0.000000 0.000000
12 0.153846 0.653846 0.831814 0.000000 0.000000 0.000000
13 0.230769 0.848133 1.278296 0.000000 0.000000 0.000000
14 0.519177 1.920417 0.000000 0.000000 0.000000 0.000000
15 0.211622 0.499214 0.000000 0.000000 0.000000 0.000000