ginnyxxxxxxx commited on
Commit
0db3acb
Β·
1 Parent(s): 023fff0

cotchange

Browse files
Files changed (1) hide show
  1. app.py +92 -51
app.py CHANGED
@@ -6,7 +6,7 @@ import os
6
  import re
7
  import json
8
 
9
- BASE = os.path.dirname(os.path.abspath(__file__))
10
  STAY_POINTS = os.path.join(BASE, "data", "stay_points_sampled.csv")
11
  POI_PATH = os.path.join(BASE, "data", "poi_sampled.csv")
12
  DEMO_PATH = os.path.join(BASE, "data", "demographics_sampled.csv")
@@ -115,46 +115,47 @@ def build_mobility_summary(agent_sp):
115
  obs_end = agent_sp["end_datetime"].max().strftime("%Y-%m-%d")
116
  days = (agent_sp["end_datetime"].max() - agent_sp["start_datetime"].min()).days
117
 
118
- lines = [
119
- "MOBILITY TRAJECTORY DATA",
120
- "===========================",
121
- f"Observation Period: {obs_start} to {obs_end} ({days} days)",
122
- f"Total Stay Points: {len(agent_sp)}",
123
- f"Unique Locations: {agent_sp['name'].nunique()}",
124
- "",
125
- "LOCATION PATTERNS",
126
- "----------------",
127
- ]
128
- for i, (name, row) in enumerate(top5.iterrows(), 1):
129
- lines += [f"{i}. {name}",
130
- f" Visits: {int(row['visits'])} times",
131
- f" Average Duration: {int(row['avg_dur'])} minutes", ""]
132
 
 
133
  agent_sp2 = agent_sp.copy()
134
  agent_sp2["hour"] = agent_sp2["start_datetime"].dt.hour
135
  def tod(h):
136
- if 5 <= h < 12: return "morning"
137
- if 12 <= h < 17: return "afternoon"
138
- if 17 <= h < 21: return "evening"
139
- return "night"
140
  agent_sp2["tod"] = agent_sp2["hour"].apply(tod)
141
- tod_pct = (agent_sp2["tod"].value_counts(normalize=True) * 100).round(0).astype(int)
142
  agent_sp2["is_weekend"] = agent_sp2["start_datetime"].dt.dayofweek >= 5
143
  wd_pct = int((~agent_sp2["is_weekend"]).mean() * 100)
144
 
145
- lines += ["TEMPORAL PATTERNS", "----------------", "Activity by Time of Day:"]
146
- for k, v in tod_pct.items():
147
- lines.append(f"- {k}: {v}%")
148
- lines += ["", "Weekday vs Weekend:",
149
- f"- weekday: {wd_pct}%", f"- weekend: {100 - wd_pct}%"]
 
 
 
 
 
 
150
  return "\n".join(lines)
151
 
152
 
153
- def build_weekly_checkin(agent_sp):
154
- lines = ["WEEKLY CHECK-IN SUMMARY", "======================="]
155
  agent_sp2 = agent_sp.copy()
156
  agent_sp2["date"] = agent_sp2["start_datetime"].dt.date
157
- for date, grp in agent_sp2.groupby("date"):
 
 
 
 
 
 
158
  dow = grp["start_datetime"].iloc[0].strftime("%A")
159
  label = "Weekend" if grp["start_datetime"].iloc[0].dayofweek >= 5 else "Weekday"
160
  lines.append(f"\n--- {dow}, {date} ({label}) ---")
@@ -166,6 +167,8 @@ def build_weekly_checkin(agent_sp):
166
  f"({int(row['duration_min'])} mins): "
167
  f"{row['name']} - {row['act_label']}"
168
  )
 
 
169
  return "\n".join(lines)
170
 
171
 
@@ -432,18 +435,41 @@ def on_select(agent_id):
432
  return map_html, raw_text, demo_text, chain_html
433
 
434
 
435
- def run_reveal(agent_id):
436
- import time
437
  agent_id = int(agent_id)
438
  s1, s2, s3 = get_cot(agent_id)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
439
 
440
- yield render_chain("", "", "", status="running1")
441
- time.sleep(0.8)
442
- yield render_chain(s1, "", "", status="running2")
443
- time.sleep(0.8)
444
- yield render_chain(s1, s2, "", status="running3")
445
- time.sleep(0.8)
446
- yield render_chain(s1, s2, s3, status="done")
 
 
 
 
447
 
448
 
449
  # ── UI ────────────────────────────────────────────────────────────────────────
@@ -470,28 +496,43 @@ with gr.Blocks(title="HiCoTraj Demo", theme=gr.themes.Soft()) as app:
470
  gr.Markdown("### Trajectory Map")
471
  map_out = gr.HTML()
472
  gr.Markdown("### NUMOSIM Raw Data")
473
- raw_out = gr.Textbox(
474
- lines=25, interactive=False,
475
- label="Mobility Summary + Weekly Check-in"
476
- )
 
 
477
 
478
  with gr.Column(scale=1):
479
  gr.Markdown("### Hierarchical Chain-of-Thought Reasoning")
480
- run_btn = gr.Button("β–Ά Run HiCoTraj", variant="primary")
481
- chain_out = gr.HTML(value=render_chain("", "", "", status="idle"))
 
482
 
483
  agent_dd.change(
484
- fn=on_select, inputs=agent_dd,
485
- outputs=[map_out, raw_out, demo_label, chain_out]
486
  )
487
  app.load(
488
- fn=on_select, inputs=agent_dd,
489
- outputs=[map_out, raw_out, demo_label, chain_out]
490
  )
491
  run_btn.click(
492
- fn=run_reveal, inputs=agent_dd,
493
- outputs=chain_out
 
 
 
 
 
 
 
 
 
 
 
 
 
494
  )
495
 
496
- if __name__ == "__main__":
497
- app.launch(share=True)
 
6
  import re
7
  import json
8
 
9
+ BASE = os.path.dirname(os.path.abspath(__file__)) if "__file__" in dir() else os.getcwd()
10
  STAY_POINTS = os.path.join(BASE, "data", "stay_points_sampled.csv")
11
  POI_PATH = os.path.join(BASE, "data", "poi_sampled.csv")
12
  DEMO_PATH = os.path.join(BASE, "data", "demographics_sampled.csv")
 
115
  obs_end = agent_sp["end_datetime"].max().strftime("%Y-%m-%d")
116
  days = (agent_sp["end_datetime"].max() - agent_sp["start_datetime"].min()).days
117
 
118
+ # Top activity types
119
+ act_counts = agent_sp["act_label"].value_counts().head(3)
120
+ top_acts = ", ".join(f"{a} ({n})" for a, n in act_counts.items())
 
 
 
 
 
 
 
 
 
 
 
121
 
122
+ # Time of day
123
  agent_sp2 = agent_sp.copy()
124
  agent_sp2["hour"] = agent_sp2["start_datetime"].dt.hour
125
  def tod(h):
126
+ if 5 <= h < 12: return "Morning"
127
+ if 12 <= h < 17: return "Afternoon"
128
+ if 17 <= h < 21: return "Evening"
129
+ return "Night"
130
  agent_sp2["tod"] = agent_sp2["hour"].apply(tod)
131
+ peak_tod = agent_sp2["tod"].value_counts().idxmax()
132
  agent_sp2["is_weekend"] = agent_sp2["start_datetime"].dt.dayofweek >= 5
133
  wd_pct = int((~agent_sp2["is_weekend"]).mean() * 100)
134
 
135
+ lines = [
136
+ f"Period: {obs_start} ~ {obs_end} ({days} days)",
137
+ f"Stay points: {len(agent_sp)} | Unique locations: {agent_sp['name'].nunique()}",
138
+ f"Weekday/Weekend: {wd_pct}% / {100-wd_pct}% | Peak time: {peak_tod}",
139
+ f"Top activities: {top_acts}",
140
+ "",
141
+ "Top Locations:",
142
+ ]
143
+ for i, (name, row) in enumerate(top5.iterrows(), 1):
144
+ lines.append(f" {i}. {name} β€” {int(row['visits'])} visits, avg {int(row['avg_dur'])} min")
145
+
146
  return "\n".join(lines)
147
 
148
 
149
+ def build_weekly_checkin(agent_sp, max_days=None):
 
150
  agent_sp2 = agent_sp.copy()
151
  agent_sp2["date"] = agent_sp2["start_datetime"].dt.date
152
+ all_dates = sorted(agent_sp2["date"].unique())
153
+ dates_to_show = all_dates[:max_days] if max_days else all_dates
154
+ total_days = len(all_dates)
155
+
156
+ lines = ["WEEKLY CHECK-IN SUMMARY", "======================="]
157
+ for date in dates_to_show:
158
+ grp = agent_sp2[agent_sp2["date"] == date]
159
  dow = grp["start_datetime"].iloc[0].strftime("%A")
160
  label = "Weekend" if grp["start_datetime"].iloc[0].dayofweek >= 5 else "Weekday"
161
  lines.append(f"\n--- {dow}, {date} ({label}) ---")
 
167
  f"({int(row['duration_min'])} mins): "
168
  f"{row['name']} - {row['act_label']}"
169
  )
170
+ if max_days and total_days > max_days:
171
+ lines.append(f"\n... ({total_days - max_days} more days)")
172
  return "\n".join(lines)
173
 
174
 
 
435
  return map_html, raw_text, demo_text, chain_html
436
 
437
 
438
+ def run_step(agent_id, step):
439
+ """Reveal one stage per click. step: 0->1->2->done(-1)"""
440
  agent_id = int(agent_id)
441
  s1, s2, s3 = get_cot(agent_id)
442
+ next_step = step + 1
443
+ if next_step == 1:
444
+ html = render_chain(s1, "", "", status="running2")
445
+ label = "β–Ά Stage 2: Behavioral Analysis"
446
+ return html, 1, gr.update(value=label)
447
+ elif next_step == 2:
448
+ html = render_chain(s1, s2, "", status="running3")
449
+ label = "β–Ά Stage 3: Demographic Inference"
450
+ return html, 2, gr.update(value=label)
451
+ else:
452
+ html = render_chain(s1, s2, s3, status="done")
453
+ return html, -1, gr.update(value="β†Ί Reset")
454
+
455
+
456
+ def handle_btn(agent_id, step):
457
+ if step == -1:
458
+ html = render_chain("", "", "", status="idle")
459
+ return html, 0, gr.update(value="β–Ά Stage 1: Feature Extraction")
460
+ return run_step(agent_id, step)
461
 
462
+
463
+ def on_select_reset(agent_id):
464
+ agent_id_int = int(agent_id)
465
+ agent_sp = sp[sp["agent_id"] == agent_id_int].sort_values("start_datetime")
466
+ agent_demo = demo[demo["agent_id"] == agent_id_int].iloc[0]
467
+ map_html = build_map(agent_sp)
468
+ demo_text = build_demo_text(agent_demo)
469
+ summary = build_mobility_summary(agent_sp)
470
+ raw_text = build_weekly_checkin(agent_sp, max_days=2)
471
+ chain_html = render_chain("", "", "", status="idle")
472
+ return map_html, summary, raw_text, demo_text, chain_html, 0, gr.update(value="β–Ά Stage 1: Feature Extraction")
473
 
474
 
475
  # ── UI ────────────────────────────────────────────────────────────────────────
 
496
  gr.Markdown("### Trajectory Map")
497
  map_out = gr.HTML()
498
  gr.Markdown("### NUMOSIM Raw Data")
499
+ with gr.Tabs():
500
+ with gr.Tab("Summary"):
501
+ summary_out = gr.Textbox(lines=10, interactive=False, label="")
502
+ with gr.Tab("Raw Data"):
503
+ raw_out = gr.Textbox(lines=10, interactive=False, label="")
504
+ show_all_btn = gr.Button("Show All Days", size="sm", variant="secondary")
505
 
506
  with gr.Column(scale=1):
507
  gr.Markdown("### Hierarchical Chain-of-Thought Reasoning")
508
+ step_state = gr.State(value=0)
509
+ run_btn = gr.Button("β–Ά Stage 1: Feature Extraction", variant="primary")
510
+ chain_out = gr.HTML(value=render_chain("", "", "", status="idle"))
511
 
512
  agent_dd.change(
513
+ fn=on_select_reset, inputs=agent_dd,
514
+ outputs=[map_out, summary_out, raw_out, demo_label, chain_out, step_state, run_btn]
515
  )
516
  app.load(
517
+ fn=on_select_reset, inputs=agent_dd,
518
+ outputs=[map_out, summary_out, raw_out, demo_label, chain_out, step_state, run_btn]
519
  )
520
  run_btn.click(
521
+ fn=handle_btn, inputs=[agent_dd, step_state],
522
+ outputs=[chain_out, step_state, run_btn]
523
+ )
524
+
525
+ def toggle_raw(agent_id, current_text):
526
+ agent_id_int = int(agent_id)
527
+ agent_sp = sp[sp["agent_id"] == agent_id_int].sort_values("start_datetime")
528
+ if "more days" in current_text:
529
+ return build_weekly_checkin(agent_sp), gr.update(value="Show Less")
530
+ else:
531
+ return build_weekly_checkin(agent_sp, max_days=2), gr.update(value="Show All Days")
532
+
533
+ show_all_btn.click(
534
+ fn=toggle_raw, inputs=[agent_dd, raw_out],
535
+ outputs=[raw_out, show_all_btn]
536
  )
537
 
538
+ app.launch(show_error=True)