במאמר הזה מוסברת הסכימה של טבלה ב-BigQuery שנוצרת כשמייצאים מטא-נתונים של DICOM ל-BigQuery.
הסברים על המונחים
כדי להבין את הסכימה ואת הרכיבים שלה, כדאי לעיין בטרמינולוגיה של DICOM. בפרט, בדף הזה נעשה שימוש בכמה מונחים שמופיעים ב3.10 DICOM Data Structures and Encoding Definitions.
סקירה כללית
Cloud Healthcare API יוצר באופן אוטומטי את הסכימה של BigQuery באמצעות הנתונים שמייצאים ומילון DICOM. הסכמה מכילה רק עמודות של רכיבי נתונים בפורמט DICOM שקיימים במטא-נתונים. היוצא מן הכלל היחיד הוא Person Name VR.
כשמייצאים מטא-נתונים של DICOM, Cloud Healthcare API מנסה לייצא את כל רכיבי הנתונים במטא-נתונים. במאמר סוגים שסותרים או לא תואמים מוסבר מה קורה אם מתעוררת בעיה.
רכיבי נתונים רגילים ופרטיים
פורמט DICOM מספק רכיבי נתונים סטנדרטיים שתואמים למפרט מוגדר מראש. רשימה של רכיבי הנתונים האלה זמינה במאגר של רכיבי נתונים ב-DICOM.
במקרים שבהם צריך להעביר נתונים שלא תואמים לרכיבים הרגילים, אפשר להשתמש ברכיבי נתונים פרטיים.
רכיבי נתונים רגילים
ההתנהגויות הבאות חלות על רכיבי נתונים רגילים. מידע על ההתנהגות של רכיבי נתונים פרטיים זמין במאמר רכיבי נתונים פרטיים.
שמות של עמודות
השמות של העמודות בסכימה שנוצרה ב-BigQuery נקבעים לפי מילת המפתח של רכיב הנתונים. לדוגמה, אם מטא-נתוני DICOM מכילים רכיב נתונים שמילת המפתח שלו היא InstanceCreationDate, אז לסכימה שנוצרת יש עמודה תואמת בשם InstanceCreationDate.
התנהגות סטנדרטית של רכיבי נתונים ב-DICOM
בטבלה הבאה מוצגת רשימה של ייצוגי ערכים (VR) והקיצורים שלהם. לכל רכיב נתונים שמיוצא ל-BigQuery ומכיל אחד מה-VR האלה, רכיב הנתונים משתמש בסוג הנתונים של BigQuery שמופיע בקטע 'סוג נתונים':
| VR | סוג נתונים |
|---|---|
|
מחרוזת |
| תאריך (DA) | תאריך |
| שעה (TM) | שעה |
| תאריך ושעה (DT) | חותמת זמן |
|
String |
| שם האדם (PN) | Struct (Record) |
|
נקודה צפה |
|
Integer |
| רצף פריטים (SQ) | Struct (Record) |
מצבים של אפשרות לערך Null וחזרה
בהתאם לערך של Value Multiplicity (VM) של רכיב נתונים, לעמודה שלו ב-BigQuery יש אחד משני מצבים: NULLABLE או REPEATED.
אם ערך ה-VM של רכיב נתונים הוא 1, מה שמציין שהרכיב הוא ייחודי, רכיב הנתונים משתמש במצב NULLABLE. לכל ערך אחר של מכונה וירטואלית,
רכיב הנתונים משתמש במצב REPEATED.
לדוגמה, כפי שמוצג במאגר של רכיבי נתונים ב-DICOM, למילת המפתח SOPInstanceUID יש ערך של מכונה וירטואלית 1. כתוצאה מכך, כשמייצאים אותו ל-BigQuery, המצב שלו הוא NULLABLE, והייצוג שלו בטבלה נראה כך (כשמייצגים אותו כ-JSON):
"SOPInstanceUID": "0.0.000.000000.0.000.0000.0000000.0000.0000000000.000",
לעומת זאת, למילת המפתח ImageType יש ערך VM של 2-n.
כתוצאה מכך, כשמייצאים אותו ל-BigQuery, המצב שלו הוא REPEATED, והייצוג שלו בטבלה נראה כך (כשמייצגים אותו כ-JSON):
"ImageType": [
"ORIGINAL",
"PRIMARY",
"OTHER",
"..."
],
החרגת סרטוני VR
נתונים בינאריים ונתונים בפורמט ארוך לא מיוצאים לטבלה שנוצרת ב-BigQuery, ולכן רכיבי נתונים שמכילים את ה-VR הבאים לא מיוצאים. במקום זאת, ערכי ה-VR הבאים כלולים בעמודה נפרדת (שנקראת DroppedTags.TagName) בטבלה ב-BigQuery.
- Other Double (OD)
- מספר ממשי אחר (OF)
- אחר, ארוך (OL)
- בייט אחר (OB)
- מילה אחרת (OW)
- לא ידוע (UN)
- תגי רצף (SQ) שמכילים יותר מ-1MiB של נתונים
- מאפיין (AT), נקודה צפה כפולה (FD), נקודה צפה יחידה (FL),
מספר שלם לא שלילי (UL) או מספר שלם לא שלילי קצר (US), אם הערך של Value Multiplicity (VM) גדול מ-512.
- מסיבות שקשורות לגרסאות קודמות, יכול להיות שתגים של מופעים שכבר הועברו אל Cloud Healthcare API ייכללו בעמודה
DroppedTags.TagNameאם הערך של Value Multiplicity גדול מ-64.
- מסיבות שקשורות לגרסאות קודמות, יכול להיות שתגים של מופעים שכבר הועברו אל Cloud Healthcare API ייכללו בעמודה
שם האדם ב-VR
כל עמודה בסכימה של BigQuery עם VR של Person Name (PN) תמיד מכילה שלוש עמודות משנה, בלי קשר לשאלה אם עמודות המשנה מכילות נתונים כלשהם. שלושת עמודות המשנה הן:
- אלפביתי
- אידאוגרפי
- פונטית
לכל אחת משלוש עמודות המשנה יש חמש עמודות משנה משלה:
- FamilyName
- GivenName
- MiddleName
- NamePrefix
- NameSuffix
לדוגמה, התג הציבורי OperatorsName (0008,1070), שיש לו VR של Person Name (PN). נניח שהערך של OperatorsName הוא Darcy Smith. הסכימה תכיל עמודה בשם OperatorsName עם עמודות המשנה שצוינו קודם, אבל רק העמודות Alphabetic.FamilyName (Smith) ו-Alphabetic.GivenName (Darcy) יכילו ערכים.
רכיבי נתונים פרטיים
יכול להיות שבחלק מהיישומים הקליניים תצטרכו לאחסן נתונים בהתאמה אישית שלא מתאימים למבנה של רכיבי נתונים ציבוריים. אפשר גם להשתמש ברכיבי נתונים פרטיים.
רכיבי נתונים פרטיים עם VR של SQ (רצף פריטים) מתנהגים כמו רכיבי נתונים רגילים. רכיבי נתונים פרטיים עם VR של SQ נקראים רצפים של נתונים פרטיים.
רכיבי נתונים פרטיים שאין להם VR של SQ מוטמעים בעמודה בשם OtherElements ומומרים למחרוזות. רכיבי הנתונים הפרטיים האלה נקראים נתונים פרטיים לא רציפים. כדי לשלוח שאילתה לגבי רכיבי נתונים פרטיים שלא קשורים לרצף, השאילתה צריכה לחפש בתוך העמודה OtherElements של הרכיב.
העמודה OtherElements מכילה שתי עמודות משנה: 'נתונים' ו'תג'. עמודת הנתונים היא ייצוג המחרוזת של הערך של רכיב הנתונים הפרטי.
הסוג הוא תמיד REPEATED. הפורמט של העמודה Tag הוא Tag_HEX, כאשר HEX הוא מחרוזת הקסדצימלית של מספר התג.
LastUpdated ו-Type עמודות
העמודות LastUpdated ו-Type מתווספות לטבלה ב-BigQuery שנוצרת כשמייצאים מטא-נתונים של DICOM. העמודות האלה לא מכילות רכיבי נתונים סטנדרטיים או פרטיים, והן לא תואמות לרישום של רכיבי נתוני DICOM.
ההתנהגות של העמודות האלה היא כזו:
- העמודה
LastUpdatedמכילה ערך של חותמת זמן שמראה מתי מופע DICOM הוכנס למאגר DICOM או נמחק ממנו. - העמודה
Typeמכילה מחרוזת שמראה איזה סוג פעולה התרחש. הערכים האפשריים הםCREATEאוDELETE.
סוגים מתנגשים ולא תואמים
אם מתרחש ניגוד בין סוגים, למשל כשמשתמשים בתג ציבורי עם סוג שגוי, המערכת מתייחסת לתג הציבורי כאילו היה תג פרטי. הערך של רכיב הנתונים מוטמע בעמודה בשם OtherElements והערך מומר למחרוזת.
לדוגמה, נניח שמטא-נתוני DICOM מכילים תג עם:
- מספר תג (4010,1017)
- ערך VR של SL (מספר שלם ארוך עם סימן)
- הערך 32
(4010,1017) הוא אותו מספר תג כמו 'Mass', שהוא שם תג ציבורי במפרט DICOM עם VR של FL. פעולת הייצוא מצפה שרכיב נתונים עם מספר התג (4010,1017) יהיה שם התג הציבורי Mass עם VR של FL. לכן, פעולת הייצוא מצפה להמיר את הערך של רכיב הנתונים למספר נקודה צפה (כפי שמוצג בטבלה בהתנהגות רגילה של רכיב נתונים ב-DICOM
התנגשות בסוג מתרחשת כי כל התגים עם VR של SL משתמשים בסוג הנתונים integer. לכן התג מומר לתג פרטי ומוסף לעמודה OtherElements.
אם משתמשים בשם תג ציבורי שאינו רצף לנתוני רצף, מתרחש חוסר התאמה בסוג. כתוצאה מכך, הרצף מטופל כאילו הוא רכיב נתונים פרטי. במקום להשתמש בשם התג הגלוי לכולם כשם העמודה בסכימת BigQuery, נעשה שימוש במספר ההקסדצימלי של שם התג הגלוי לכולם. המספר ההקסדצימלי הוא מסוג מחרוזת.
דוגמאות: שליחת שאילתות לגבי רכיבי נתונים ציבוריים ופרטיים
הנה קטע של סכימה שמוצג כ-JSON. הסכימה נוצרה אחרי ייצוא נתוני DICOM ל-BigQuery.
[
...
{
"name": "SOPInstanceUID",
"type": "STRING"
},
{
"fields": [
{
"fields": [
{
"mode": "REQUIRED",
"name": "Tag",
"type": "STRING"
},
{
"mode": "REPEATED",
"name": "Data",
"type": "STRING"
}
],
"mode": "REPEATED",
"name": "OtherElements",
"type": "RECORD"
}
],
"mode": "REPEATED",
"name": "Tag_12345678",
"type": "RECORD"
}
...
]
בדוגמה הבאה אפשר לראות איך שולחים שאילתה לגבי רכיב הנתונים הציבורי SOPInstanceUID.
כדי לגשת לערך של העמודה, מריצים את השאילתה הבאה:
#standardSQL SELECT SOPInstanceUID FROM `PROJECT_ID.DATASET_ID.TABLE_ID`
הרצת השאילתה מחזירה פלט שדומה לזה:
[ ... { "SOPInstanceUID": "0.0.000.000000.0.000.0000.0000000.0000.0000000000.000" }, ... ]
בדוגמה הבאה אפשר לראות איך שולחים שאילתה לגבי נתונים פרטיים שאינם רציפים.
מריצים את השאילתה הבאה על העמודה OtherElements שנמצאת בתוך העמודה Tag_12345678. שימו לב לשימוש באופרטור UNNEST, שהוא חובה כי אתם שולחים שאילתה ל-RECORD.
#standardSQL SELECT Tag_12345678.OtherElements AS OtherElements FROM `PROJECT_ID.DATASET_ID.TABLE_ID`, UNNEST(Tag_12345678) AS Tag_12345678
הרצת השאילתה מחזירה פלט שדומה לזה שמוצג בהמשך, בהתאם לכמות ולסוג הנתונים בעמודה Tag_12345678.OtherElements:
[ { "OtherElements": [ { "Tag": "Tag_12345678", "Data": [ "DATA" ] } ] }, { "OtherElements": [ { "Tag": "Tag_12345678", "Data": [ "DATA" ] } ] }, { "OtherElements": [ { "Tag": "Tag_12345678", "Data": [ "DATA" ] } ] } ]
סכימת JSON
אתם יכולים לייצא מטא-נתונים של מופע DICOM לטבלה ב-BigQuery עם סכימה פשוטה יותר, שבה המטא-נתונים המלאים של המופע מאוחסנים כעמודת JSON אחת. האפשרות הזו יכולה להיות שימושית אם אתם מעדיפים לעבוד עם מבנה ה-JSON הגולמי של מטא-נתוני DICOM ב-BigQuery. האפשרות הזו שימושית גם כשמספר התגים הייחודיים בכל מופעי DICOM חורג מהמספר המקסימלי של העמודות שמותרות בטבלה ב-BigQuery.
כדי להפעיל את סכימת ה-JSON, מגדירים את השדה schema_json ב-BigQueryDestination. פרטים נוספים על הגדרת הסכימה זמינים במאמר BigQueryDestination.
כשהסכימה של ה-JSON מופעלת, בטבלה ב-BigQuery מופיעות העמודות הבאות:
| שם השדה | סוג | תיאור |
|---|---|---|
StudyInstanceUID |
מחרוזת | תג DICOM (0020,000D). |
SeriesInstanceUID |
מחרוזת | תג DICOM (0020,000E). |
SOPInstanceUID |
מחרוזת | תג DICOM (0008,0018). |
SourceDicomStore |
מחרוזת | השם של מאגר ה-DICOM של המקור. השדה הזה נכלל רק אם האפשרות includeSourceStore מוגדרת כ-True בהגדרות הייצוא. |
Type |
מחרוזת | מציין את סוג הפעולה שהפעילה את הייצוא (לדוגמה, CREATE, DELETE). |
LastUpdated |
TIMESTAMP | חותמת הזמן של העדכון האחרון של המופע במאגר DICOM. |
Metadata |
JSON | כל תגי ה-DICOM של המופע, מאוחסנים באובייקט JSON יחיד. |
DroppedTags |
REPEATED STRING | רשימה של תגים שהושמטו במהלך ההמרה, בדרך כלל תגים בינאריים או תגים גדולים מאוד. |
StorageClass |
מחרוזת | סוג האחסון של המופע (למשל, STANDARD, NEARLINE). |
BlobStorageSize |
מספר שלם | גודל אחסון ה-Blob בבייטים. |
StructuredStorageSize |
מספר שלם | גודל האחסון המובנה בבייטים. |
דוגמה: שאילתה בעמודת ה-JSON של המטא-נתונים
הנה דוגמה לשאילתה של תג DICOM ספציפי מהעמודה Metadata בהתאם לתמיכה בנתוני JSON ב-BigQuery. השאילתה הזו בוחרת את התגים PatientID ו-PatientAge:
#standardSQL SELECT Metadata.PatientID AS patient_id, Metadata.PatientAge AS patient_age FROM `PROJECT_ID.DATASET_ID.TABLE_ID`;
הרצת השאילתה מחזירה פלט שדומה לזה:
/*-------------+---------------*
| patient_id | patient_age |
+--------------+---------------+
| "John-Doe" | "042Y" |
*--------------+---------------*/
אפשר לשנות את השאילתה כדי לחלץ תגי DICOM אחרים מעמודת ה-JSON של Metadata לפי הצורך.
המאמרים הבאים
מידע נוסף על פעולות ב-BigQuery Standard SQL ודוגמאות