Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: Add schedule for the standard imaging protocol #490

Merged
merged 2 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 60 additions & 9 deletions code/sessions/hcph-sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,17 @@
import datetime
import random
import click
from collections import defaultdict
import pandas as pd


SCANNER_NAME_MAPPINGS = {
"Prisma": "060",
"Vida07": "034",
"VidaFit": "030",
}


@click.group()
@click.version_option(message="HCPh Session Generator")
def cli() -> None:
Expand All @@ -44,6 +52,7 @@ def cli() -> None:
@click.option("-s", "--seed", type=click.IntRange(min=0), default=20231020)
@click.option("-o", "--output", type=click.File("w"))
@click.option("-n", "--num-sessions", type=click.IntRange(min=1), default=36)
@click.option("-i", "--scanner-ids", type=str, multiple=True)
@click.option(
"--base-date", type=click.DateTime(formats=["%Y-%m-%d"]), default="2023-10-20"
)
Expand All @@ -53,6 +62,7 @@ def generate(
seed: int,
output: click.utils.LazyFile,
num_sessions: int,
scanner_ids: list[str],
base_date: datetime.date,
sessions_per_day: int,
md_output: click.utils.LazyFile,
Expand All @@ -68,6 +78,8 @@ def generate(
File to write the session plan in a tabular format.
num_sessions : int
Number of sessions to generate.
scanner_ids : list
Identifiers of the scanners (shuffles order).
base_date : datetime.date
Base date for session scheduling.
sessions_per_day : int
Expand All @@ -84,21 +96,60 @@ def generate(
"""

random.seed(seed)

num_devices = len(scanner_ids)

sessions = list(range(1, num_sessions + 1))
encodings = (["LR", "RL", "PA", "AP"] * (num_sessions // 4 + 1))[:num_sessions]
random.shuffle(encodings)
days = [
base_date + datetime.timedelta(days=delta)
for s in range(num_sessions)
for delta in [s] * sessions_per_day
][:num_sessions]
table = pd.DataFrame(
{
"session": sessions,
"day": days,
"PE": encodings,
}
)

datadict = defaultdict(list)
for sid in scanner_ids:
encodings = (["LR", "RL", "PA", "AP"] * (num_sessions // 4 + 1))[:num_sessions]
random.shuffle(encodings)

if num_devices == 1:
datadict = {
"session": sessions,
"day": days,
"PE": encodings,
}
else:
datadict["day"] += days
datadict["device"] += [sid] * num_sessions
datadict["session"] += sessions
datadict["PE"] += encodings

table = pd.DataFrame(datadict)

if num_devices > 1:
indexes = list(range(len(table)))
random.shuffle(indexes)

table = table.iloc[indexes].sort_values(["day", "session"])

table["sessionwise_order"] = [2, 3, 4] * num_sessions
table.loc[table["device"] == "Prisma", "sessionwise_order"] = 1
table = table.sort_values(["day", "session", "sessionwise_order"])
table["sessionwise_order"] = [1, 2, 3] * num_sessions

table["bids_id"] = [
f"{row['session']:03d}{row['sessionwise_order']:02d}"
f"{SCANNER_NAME_MAPPINGS[row['device']]}"
for _, row in table.iterrows()
]
table.reset_index(drop=True)
table.drop(labels=["sessionwise_order"], axis=1, inplace=True)

table["day"] = table["day"].apply(lambda x: x.date())

# print(table.to_markdown(index=False))
# print(table[table["device"] == "Prisma"].to_markdown(index=False))
# print(table[table["device"] == "Vida07"].to_markdown(index=False))
# print(table[table["device"] == "VidaFit"].to_markdown(index=False))

if output:
table.to_csv(output, index=None, sep="\t")
Expand Down
38 changes: 38 additions & 0 deletions code/sessions/schedule-wave2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
| day | device | session | PE | bids_id |
|:-----------|:---------|----------:|:-----|----------:|
| 2024-08-20 | Prisma | 1 | AP | 00101060 |
| 2024-08-20 | VidaFit | 1 | RL | 00102030 |
| 2024-08-20 | Vida07 | 1 | PA | 00103034 |
| 2024-08-21 | Prisma | 2 | RL | 00201060 |
| 2024-08-21 | VidaFit | 2 | AP | 00202030 |
| 2024-08-21 | Vida07 | 2 | RL | 00203034 |
| 2024-08-22 | Prisma | 3 | LR | 00301060 |
| 2024-08-22 | Vida07 | 3 | PA | 00302034 |
| 2024-08-22 | VidaFit | 3 | AP | 00303030 |
| 2024-08-23 | Prisma | 4 | PA | 00401060 |
| 2024-08-23 | Vida07 | 4 | RL | 00402034 |
| 2024-08-23 | VidaFit | 4 | RL | 00403030 |
| 2024-08-24 | Prisma | 5 | RL | 00501060 |
| 2024-08-24 | VidaFit | 5 | PA | 00502030 |
| 2024-08-24 | Vida07 | 5 | LR | 00503034 |
| 2024-08-25 | Prisma | 6 | PA | 00601060 |
| 2024-08-25 | VidaFit | 6 | LR | 00602030 |
| 2024-08-25 | Vida07 | 6 | RL | 00603034 |
| 2024-08-26 | Prisma | 7 | AP | 00701060 |
| 2024-08-26 | VidaFit | 7 | AP | 00702030 |
| 2024-08-26 | Vida07 | 7 | AP | 00703034 |
| 2024-08-27 | Prisma | 8 | LR | 00801060 |
| 2024-08-27 | Vida07 | 8 | LR | 00802034 |
| 2024-08-27 | VidaFit | 8 | PA | 00803030 |
| 2024-08-28 | Prisma | 9 | PA | 00901060 |
| 2024-08-28 | Vida07 | 9 | AP | 00902034 |
| 2024-08-28 | VidaFit | 9 | LR | 00903030 |
| 2024-08-29 | Prisma | 10 | LR | 01001060 |
| 2024-08-29 | Vida07 | 10 | AP | 01002034 |
| 2024-08-29 | VidaFit | 10 | PA | 01003030 |
| 2024-08-30 | Prisma | 11 | AP | 01101060 |
| 2024-08-30 | VidaFit | 11 | LR | 01102030 |
| 2024-08-30 | Vida07 | 11 | PA | 01103034 |
| 2024-08-31 | Prisma | 12 | RL | 01201060 |
| 2024-08-31 | Vida07 | 12 | LR | 01202034 |
| 2024-08-31 | VidaFit | 12 | RL | 01203030 |
37 changes: 37 additions & 0 deletions code/sessions/schedule-wave2.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
day device session PE bids_id
2024-08-20 Prisma 1 AP 00101060
2024-08-20 VidaFit 1 RL 00102030
2024-08-20 Vida07 1 PA 00103034
2024-08-21 Prisma 2 RL 00201060
2024-08-21 VidaFit 2 AP 00202030
2024-08-21 Vida07 2 RL 00203034
2024-08-22 Prisma 3 LR 00301060
2024-08-22 Vida07 3 PA 00302034
2024-08-22 VidaFit 3 AP 00303030
2024-08-23 Prisma 4 PA 00401060
2024-08-23 Vida07 4 RL 00402034
2024-08-23 VidaFit 4 RL 00403030
2024-08-24 Prisma 5 RL 00501060
2024-08-24 VidaFit 5 PA 00502030
2024-08-24 Vida07 5 LR 00503034
2024-08-25 Prisma 6 PA 00601060
2024-08-25 VidaFit 6 LR 00602030
2024-08-25 Vida07 6 RL 00603034
2024-08-26 Prisma 7 AP 00701060
2024-08-26 VidaFit 7 AP 00702030
2024-08-26 Vida07 7 AP 00703034
2024-08-27 Prisma 8 LR 00801060
2024-08-27 Vida07 8 LR 00802034
2024-08-27 VidaFit 8 PA 00803030
2024-08-28 Prisma 9 PA 00901060
2024-08-28 Vida07 9 AP 00902034
2024-08-28 VidaFit 9 LR 00903030
2024-08-29 Prisma 10 LR 01001060
2024-08-29 Vida07 10 AP 01002034
2024-08-29 VidaFit 10 PA 01003030
2024-08-30 Prisma 11 AP 01101060
2024-08-30 VidaFit 11 LR 01102030
2024-08-30 Vida07 11 PA 01103034
2024-08-31 Prisma 12 RL 01201060
2024-08-31 Vida07 12 LR 01202034
2024-08-31 VidaFit 12 RL 01203030
16 changes: 12 additions & 4 deletions docs/data-collection/participant-prep.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,23 @@
- [ ] In case of discovering any previously undisclosed contraindication, the volunteer **MUST NOT** participate in the study.

- [ ] Load the adequate protocol ([guidelines here](notes-scanning.md#preparing-the-protocol)).
**Verify you are loading the appropriate phase-encoding (PE) direction corresponding to the session.**
**Verify you are loading the appropriate phase-encoding (PE) direction corresponding to the session** by checking the appropriate
schedule below (today is <mark>{{ now() }}</mark>).

???+ important "Session schedule"
??? important "Session schedule: *Reliability imaging protocol*"

<a name="session-schedule"></a>
Today is <mark>{{ now() }}</mark>:
<a name="session-schedule-reliability"></a>

{% filter indent(width=8) %}
{% include 'code/sessions/schedule.md' %}
{% endfilter %}

??? important "Session schedule: *Standard imaging protocol*"

<a name="session-schedule-standard"></a>

{% filter indent(width=8) %}
{% include 'code/sessions/schedule-wave2.md' %}
{% endfilter %}

---
Expand Down
4 changes: 3 additions & 1 deletion docs/data-collection/tear-up.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,9 @@ A laptop should be available to fill the issue.
![](../assets/images/session_issue_template.png)
- [ ] Click on <span class="consolebutton green">Get started</span> on the issue template `Scan session`.
- [ ] Modify the title of the issue by replacing `yyy` with the session index.
If you don't remember the session index of today, check the [session index table](participant-prep.md#session-schedule).
If you don't remember the session index of today, check the session index table corresponding to the acquisition protocol:
[reliability imaging protocol](participant-prep.md#session-schedule-reliability),
or [standard imaging protocol](participant-prep.md#session-schedule-standard).
- [ ] Verify that your phone is on ringing mode so the participants can reach you.
- [ ] Check the time regularly to be on time to meet with the participant at the predefined location

Expand Down