# דו"ח משימה 2 – הבאת נתונים מ-IMS (Israel Meteorological Service) --- ## אילו נתונים נלקחים מ-IMS ואיך הם נשמרים ### מקור הנתונים - **שירות:** IMS (Israel Meteorological Service) – שירות המטאורולוגיה הישראלי. - **ממשק:** API Envista – `https://api.ims.gov.il/v1/envista/stations/{STATION_ID}/data/{CHANNEL_ID}/?from=YYYY/MM/DD&to=YYYY/MM/DD` - **תחנה:** **43 – שדה בוקר** (דומה לאקלים ירוחם; מיקום הכרם). - **אימות:** טוקן API ב־משתנה סביבה `IMS_API_TOKEN` (נשמר מקומית ב־`.env`, לא ב־git). ### ערוצים (Channels) שנלקחים מזהי הערוצים תלויים בתחנה. **לתחנה 43 (שדה בוקר)** מוגדרים ב־`config/dev.yaml` תחת `ims:`: | ערוץ IMS (מזהה) | שם IMS | משתנה בפלט (סכמה קנונית) | יחידות | תיאור | |-----------------|--------|---------------------------|--------|--------| | 6 | TD | `air_temperature_c` | °C | טמפרטורת אוויר נוכחית | | 8 | TDmax| `tdmax_c` | °C | טמפרטורת מקסימום (במהלך המרווח) | | 9 | TDmin| `tdmin_c` | °C | טמפרטורת מינימום (במהלך המרווח) | | 10 | Grad | `ghi_w_m2` | W/m²| קרינה גלובלית אופקית (GHI) | - אם `channel_radiation` מוגדר כ־`null` בתצורה (תחנה ללא Grad), עמודת הקרינה לא נמשכת ומופיעה רק טמפרטורה. ### טווח זמן ורזולוציה - **טווח ברירת מחדל:** שנתיים אחורה מתאריך ההרצה (ניתן לשנות עם `--from`, `--to` או `--years`). - **רזולוציה:** נתוני IMS בתדירות 10 דקות; נשמרים כפי שהתקבלו (לא מצוננים). - **בקשות:** טווח של יותר מ־60 יום מפוצל לחלקים (chunks) כדי למנוע תגובות ריקות מה־API; בין בקשות יש השהייה קצרה. ### עיבוד לפני שמירה 1. **המרת זמן:** חותמות הזמן מגיעות מ־IMS בזמן ישראל (UTC+2/UTC+3). כל התאריכים מומרים ל־**UTC** לפני שמירה. 2. **מיזוג ערוצים:** כל ערוץ נמשך בנפרד; השורות ממוזגות לפי `timestamp_utc` (איחוד אינדקסים – חסרים מסומנים כ־NaN). 3. **סינון טמפרטורה:** ערכים מחוץ לטווח **־50 עד 60 °C** (למשל ערוץ Time hhmm שנדבק בטעות) מוחלפים ב־NaN. 4. **מקור:** נוספת עמודה `source` עם הערך `ims`. ### איפה ואיך נשמרים הנתונים | פריט | ערך | |------|-----| | **קובץ פלט** | `data/ims_radiation_temperature.csv` (נתיב: `config.data_paths.IMS_RADIATION_TEMPERATURE_CSV`) | | **פורמט** | CSV (פסיק כמפריד) | | **קידוד** | ברירת מחדל של pandas (בדרך כלל UTF-8) | **עמודות בקובץ:** | עמודה | תיאור | יחידות | |--------|--------|--------| | `timestamp_utc` | חותמת זמן (UTC) | ISO format, timezone-aware UTC | | `air_temperature_c` | טמפרטורת אוויר | °C | | `tdmax_c` | טמפרטורה מקסימלית | °C | | `tdmin_c` | טמפרטורה מינימלית | °C | | `ghi_w_m2` | קרינה גלובלית אופקית (Grad) | W/m² | | `source` | מקור הנתון | תמיד `ims` | - עמודות שלא נמשכו (למשל קרינה אם אין ערוץ Grad) לא יופיעו או יהיו ריקות. - שורות עם NaN בחלק מהעמודות אפשריות (למשל אי־התאמה בזמנים בין ערוצים). ### שימוש בנתונים בפרויקט - הקובץ משמש כ־**מקור מטאורולוגיה (IMS)** ל־**Ground Truth** (משימה 1 – Data fusion). - סקריפטים נוספים: `scripts/gap_fill_future.py` ממלא פערים (כולל עתיד) ויכול לכתוב ל־`data/ims_radiation_temperature_gap_filled.csv`; `scripts/build_ground_truth.py` ממיר/ממזג ל־Ground Truth (Parquet) לפי הסכמה ב־`context/05_ground_truth_schema.md`. ### ארגון הנתונים (ת pipeline) סדר העבודה לפי התיעוד: 1. **הורדת IMS (גולמי)** `python -m scripts.download_ims_data` → פלט: `data/ims_radiation_temperature.csv` (רזולוציה 10 דקות, UTC, סינון טמפרטורה -50..60 °C). 2. **השלמת פערים (כולל עתיד)** `python -m scripts.gap_fill_future --input data/ims_radiation_temperature.csv` → פלט: `data/ims_radiation_temperature_gap_filled.csv` (רשת רגולרית, quality_flag). 3. **בניית Ground Truth (Parquet)** `python -m scripts.build_ground_truth` → פלט: `data/ground_truth/ground_truth_2024_2025.parquet` + `ground_truth_metadata.json` (רזולוציה 15 דקות). הרצת כל הצעדים ברצף (אם קיים קובץ גולמי): ```bash python -m scripts.download_ims_data && \ python -m scripts.gap_fill_future --input data/ims_radiation_temperature.csv && \ python -m scripts.build_ground_truth ``` או עדכון אוטומטי (כולל TB/DB): `python -m scripts.update_ground_truth`. --- ## נספח – פקודות API (מקור: השירות המטאורולוגי) תיעוד זה מבוסס על המסמך הרשמי **"ממשק עבור מאגר הנתונים המטאורולוגיים העשר דקתיים"** – משרד התחבורה, השירות המטאורולוגי (תאריך עדכון 11.05.2017). מקור: קובץ "פקודות API" מהשמ"ט. כ־85 תחנות אוטומטיות; הנתונים נמשכים בפורמט JSON. ### אימות (Authorization) - **שיטה:** `Authorization: ApiToken XXXX` - **קבלת TOKEN:** פנייה במייל ל־**ims@ims.gov.il** - בפרויקט: משתנה סביבה `IMS_API_TOKEN` (נשמר ב־`.env`). ### מוסכמת זמן - **כל השנה לפי זמן מקומי תקני (LST)** – שעון חורף. - בתקופת שעון קיץ יש הפרש של שעה בין `datetime` המוצג לזמן בפועל (למשל אוקטובר: 11:40+03:00 מוצג בעוד שבפועל 12:40). - בסקריפט שלנו: כל חותמות הזמן מומרות ל־**UTC** לפני שמירה. ### מטה־דאטה: תחנות ואזורים מזהי מק placeholders: `{%ST_ID%}` = מספר תחנה, `{%REG_ID%}` = מספר אזור, `{%CH_ID%}` = מספר ערוץ. תאריך: `YYYY/MM/DD`, `MM` = חודש (למשל 05), `DD` = יום (למשל 28). **תחנות:** | תיאור | כתובת | |--------|--------| | מידע על כל התחנות | `https://api.ims.gov.il/v1/envista/stations` | | מידע על תחנה ספציפית | `https://api.ims.gov.il/v1/envista/stations/{%ST_ID%}` | תגובת תחנה כוללת: `name`, `location`, `regionId`, `monitors` (רשימת ערוצים). לכל ערוץ: `active`, `channelId`, `name`, `typeId`, `units`. **אזורים:** | תיאור | כתובת | |--------|--------| | מידע על כל האזורים (כולל תחנות) | `https://api.ims.gov.il/v1/envista/regions` | | מידע על אזור ספציפי | `https://api.ims.gov.il/v1/envista/regions/{%REG_ID%}` | אזור כולל: מספר אזור, שם, רשימת תחנות והערוצים שלהן. ### משיכת נתונים מטאורולוגיים מתחנה בסיס: `https://api.ims.gov.il/v1/envista/stations/{%ST_ID%}/data/...` **נתונים אחרונים / ישנים ביותר:** | תיאור | כתובת | |--------|--------| | אחרונים – כל הערוצים | `.../stations/{%ST_ID%}/data/latest` | | אחרונים – ערוץ ספציפי | `.../stations/{%ST_ID%}/data/{%CH_ID%}/latest` | | ישנים ביותר – כל הערוצים | `.../stations/{%ST_ID%}/data/earliest` | | ישנים ביותר – ערוץ ספציפי | `.../stations/{%ST_ID%}/data/{%CH_ID%}/earliest` | **היום / החודש הנוכחי:** | תיאור | כתובת | |--------|--------| | נתונים מהיום – כל הערוצים | `.../stations/{%ST_ID%}/data/daily` | | נתונים מהיום – ערוץ ספציפי | `.../stations/{%ST_ID%}/data/{%CH_ID%}/daily` | | נתונים מהחודש – כל הערוצים | `.../stations/{%ST_ID%}/data/monthly` | | נתונים מהחודש – ערוץ ספציפי | `.../stations/{%ST_ID%}/data/{%CH_ID%}/monthly` | **יום / חודש מסוים:** | תיאור | כתובת | |--------|--------| | יום מסוים – כל הערוצים | `.../stations/{%ST_ID%}/data/daily/YYYY/MM/DD` | | יום מסוים – ערוץ ספציפי | `.../stations/{%ST_ID%}/data/daily/{%CH_ID%}/YYYY/MM/DD` | | חודש מסוים – כל הערוצים | `.../stations/{%ST_ID%}/data/monthly/YYYY/MM` | | חודש מסוים – ערוץ ספציפי | `.../stations/{%ST_ID%}/data/{%CH_ID%}/monthly/YYYY/MM` | **טווח תאריכים (זה מה שהסקריפט משתמש בו):** | תיאור | כתובת | |--------|--------| | טווח – כל הערוצים | `.../stations/{%ST_ID%}/data?from=YYYY/MM/DD&to=YYYY/MM/DD` | | טווח – ערוץ ספציפי | `.../stations/{%ST_ID%}/data/{%CH_ID%}?from=YYYY/MM/DD&to=YYYY/MM/DD` | ### מבנה תגובת נתונים - **מספר התחנה** - **זמן המדידה** (`datetime`) - **רשימת ערוצים**, לכל ערוץ: - `id` – מס' ערוץ - `name` – שם הערוץ - `status` – **1** = תקין, **2** = לא תקין (כאשר Status=2 הנתונים לא תקינים) - `valid` – `true` / `false` - ערך מספרי של הפרמטר הנמדד **הערה:** לא כל התחנות מודדות את כל המשתנים; **מס' הערוץ לאותו משתנה יכול להיות שונה מתחנה לתחנה**. כדי לדעת את מס' הערוץ – להריץ מטה־דאטה על התחנה (או `--list-stations` בסקריפט). ### רשימת משתנים מטאורולוגיים (CHANNEL) – נספח ג' משתנים שהתחנות עשויות למדוד (שם הערוץ ב-API, יחידות, תיאור): | משתנה | יחידות | תיאור | |--------|--------|--------| | BP | mb | לחץ בגובה התחנה | | DiffR | w/m² | קרינה מפוזרת | | Grad | w/m² | קרינה גלובלית (GHI) | | NIP | w/m² | קרינה ישירה | | Rain | mm | כמות גשם | | RH | % | לחות יחסית | | STDwd | deg | סטיית תקן של כיוון הרוח | | TD | degC | טמפרטורה יבשה (אוויר) | | TDmax | degC | טמפרטורת מקסימום | | TDmin | degC | טמפרטורת מינימום | | TG | degC | טמפרטורה ליד הקרקע | | Time | hhmm | זמן סיום 10 הדקות המקסימליות | | WD | deg | כיוון הרוח | | WDmax | deg | כיוון המשב העליון | | WS | m/sec | מהירות הרוח | | Ws10mm | m/sec | מהירות רוח 10 דקתית מקסימלית | | WS1mm | m/sec | מהירות רוח דקתית מקסימלית | | WSmax | m/sec | מהירות המשב העליון | בפרויקט נמשכים כיום: **TD, TDmax, TDmin, Grad** (תחנה 43 – שדה בוקר). שאר המשתנים (לחץ, גשם, רוח, לחות, קרינה מפוזרת/ישירה וכו') זמינים באותו API לפי מס' ערוץ לכל תחנה. ### שימוש ב-Fiddler (נספח ב') לבדיקות: כלי חינמי Fiddler. ב-Composer: GET עם הכתובת הרצויה, וב־Header: `Authorization: ApiToken XXXX`. --- ## מה בוצע ### 1. סקריפט הורדת נתונים IMS (`scripts/download_ims_data.py`) - **מטרה:** הורדת נתונים היסטוריים של קרינה (Grad ≈ GHI) וטמפרטורה (TD, TDmax, TDmin) מ-IMS לשנתיים אחורה. - **API:** `https://api.ims.gov.il/v1/envista/stations/{STATION_ID}/data/{CHANNEL_ID}/?from=YYYY/MM/DD&to=YYYY/MM/DD` - **אימות:** טוקן IMS – לבקש מ-ims@ims.gov.il (תנאי שימוש: https://ims.gov.il/en/ObservationDataAPI). - **משתנה סביבה:** `IMS_API_TOKEN` (או `IMS_TOKEN`) – מומלץ להגדיר ב־`.env`. - **תצורה:** תחנה וערוצים ב־`config/dev.yaml` תחת `ims:` (ברירת מחדל: תחנה **43 – שדה בוקר**, דומה לירוחם; תחנה 98 = נבטים). - **פלט:** `data/ims_radiation_temperature.csv` עם עמודות קנוניות: `timestamp_utc`, `air_temperature_c`, `ghi_w_m2`, `tdmax_c`, `tdmin_c`, `source=ims`. חותמות הזמן מומרות מישראל (UTC+2/3) ל-UTC. **שימוש:** ```bash # רשימת תחנות (דורש טוקן) python -m scripts.download_ims_data --list-stations # הורדה לשנתיים אחורה (ברירת מחדל) python -m scripts.download_ims_data # טווח תאריכים ידני python -m scripts.download_ims_data --from 2024-01-01 --to 2025-12-31 --station 43 ``` **הערה:** מזהי הערוצים (channel IDs) תלויים בתחנה; יש לאמת מול ה-API או תיעוד IMS (למשל תחנה 28: TDmax=10, TDmin=11). --- ### 2. סקריפט השלמת פערים לעתיד (`scripts/gap_fill_future.py`) - **מטרה:** השלמת פערים בעתיד – רשת זמן רגולרית מהתאריך האחרון בנתונים עד תאריך סיום (אופציונלי), עם מילוי פערים ב-forward-fill או אינטרפולציה ליניארית, ואופציה למיזוג עם קובץ תחזית (למשל Open-Meteo). - **קלט:** קובץ IMS (או כל CSV עם `timestamp_utc` + עמודות מספריות). - **פלט:** `data/ims_radiation_temperature_gap_filled.csv` עם עמודה `quality_flag`: `observed` | `forward_fill` | `interpolated` | `forecast`. **שימוש:** ```bash # השלמת פערים עם forward-fill עד סוף הנתונים python -m scripts.gap_fill_future --input data/ims_radiation_temperature.csv # הארכת רשת עד תאריך עתידי python -m scripts.gap_fill_future --input data/ims_radiation_temperature.csv --end-date 2026-12-31 # מילוי עתיד מתחזית (למשל weather_forecast_cache) python -m scripts.gap_fill_future --input data/ims_radiation_temperature.csv --forecast data/weather_forecast_cache.csv ``` --- ### 3. עדכוני קונפיגורציה - **`config/data_paths.py`:** נוספו `IMS_RADIATION_TEMPERATURE_CSV`, `IMS_GAP_FILLED_CSV` ו-CSV_SPECS מתאימים. - **`config/dev.yaml`:** נוסף בלוק `ims:` עם `station_id`, `default_station_id`, ו-channel IDs (ניתן להתאמה לפי תחנה). - **`config/env.example`:** נוסף `IMS_API_TOKEN` עם הערה לבקשת טוקן. --- ## מה נשאר (אופציונלי) - **ולידציה:** להריץ הורדה עם טוקן אמיתי ולוודא כיסוי ורזולוציה (שעתי/יומי) מול דרישות Ground Truth. - **התאמת תחנה/ערוצים:** תחנה 43 = שדה בוקר (דומה לירוחם), תחנה 98 = נבטים. להריץ `--list-stations` לעדכון תחנה/ערוצים. --- ## סיכום | פריט | סטטוס | |------|--------| | תיעוד/גישה ל-IMS API | בוצע – תיעוד וסקריפט | | סקריפט הורדה (שנתיים אחורה) | בוצע – `download_ims_data.py` | | מיפוי לסכמה קנונית + CSV | בוצע – `timestamp_utc`, `air_temperature_c`, `ghi_w_m2`, וכו' | | סקריפט השלמת פערים לעתיד | בוצע – `gap_fill_future.py` | | ולידציה כיסוי/רזולוציה | ממתין – דורש טוקן IMS והרצה |