From 4ad757f04d9aef788d8749c9473200955f9dc34d Mon Sep 17 00:00:00 2001 From: Gayatri Aniruddha Date: Thu, 10 Oct 2024 17:12:49 +0800 Subject: [PATCH] extra files removed --- download_data_casda/automate_download.py | 42 --- download_data_casda/casda_download_austin.py | 293 ------------------ .../casda_download_wallaby-hires.py | 4 +- .../casda_download_wallaby-hires_test.py | 31 -- download_data_casda/tap_query_practice.ipynb | 254 --------------- 5 files changed, 2 insertions(+), 622 deletions(-) delete mode 100644 download_data_casda/automate_download.py delete mode 100644 download_data_casda/casda_download_austin.py delete mode 100644 download_data_casda/casda_download_wallaby-hires_test.py delete mode 100644 download_data_casda/tap_query_practice.ipynb diff --git a/download_data_casda/automate_download.py b/download_data_casda/automate_download.py deleted file mode 100644 index 79d2a65..0000000 --- a/download_data_casda/automate_download.py +++ /dev/null @@ -1,42 +0,0 @@ -''' -Start date: -23/07/24 (noted) -31/07/24 (actual) -End date: -What: Code to automatically download .ms files from casda to Setonix/laptop. - -Links from Austin: -https://astroquery.readthedocs.io/en/latest/casda/casda.html -https://github.com/AusSRC/pipeline_components/blob/main/casda_download/casda_download.py - -Self links: -1) DALiuGE (Wallaby) -Link: https://docs.google.com/document/d/1P9zukHujRgKNsYbltH9Z0oZnUttMBhXVQUIz_N_mj_o/edit -How to download an observation from CASDA (on Setonix)? - -2) Benchmarks -https://docs.google.com/spreadsheets/d/1KDzBG3_VFEl17mp58S_I8pN0V_vJBz9Xt-mx3x0fabM/edit?gid=1846631247#gid=1846631247 - -3) Total -As of 31/07/24 -- Total sources: 62 -- Total .ms files: 380 (As each source has around 4-12 fp data) -Results: - -Main keyword: HIPASS*_*10arc_split.ms - -Test observation to download: -HIPASSJ1318-21_A_beam10_10arc_split (1 fp) -HIPASSJ1318-21*_*10arc_split (all 6 fp) - -HIPASS*_*10arc_split (generic) - -Generic link to download: -https://data.csiro.au/domain/casdaObservation?dataProducts=%5B%7B%22dataProduct%22%3A%22CATALOGUE%22%7D,%7B%22dataProduct%22%3A%22IMAGE_CUBE%22%7D,%7B%22dataProduct%22%3A%22IMAGE_CUBE_ANCILLARY%22%7D,%7B%22dataProduct%22%3A%22SPECTRUM%22%7D,%7B%22dataProduct%22%3A%22MEASUREMENT_SET%22%7D%5D&facets=%5B%5D&showRejected=false&releasedFilter=released&includeCommensalProjects=false&showFacets=true&telescopes=%5B%22ASKAP%22%5D&atcaArray=%5B%5D&searchType=ASKAP&project=AS102%20-%20ASKAP%20Pilot%20Survey%20for%20WALLABY - - -Specific link to download with the following value prefilled: Filename: "HIPASS*_*10arc_split" -https://data.csiro.au/domain/casdaObservation?dataProducts=%5B%7B%22dataProduct%22%3A%22CATALOGUE%22%7D,%7B%22dataProduct%22%3A%22IMAGE_CUBE%22%7D,%7B%22dataProduct%22%3A%22IMAGE_CUBE_ANCILLARY%22%7D,%7B%22dataProduct%22%3A%22SPECTRUM%22%7D,%7B%22dataProduct%22%3A%22MEASUREMENT_SET%22%7D%5D&facets=%5B%5D&showRejected=false&releasedFilter=released&includeCommensalProjects=false&showFacets=true&telescopes=%5B%22ASKAP%22%5D&atcaArray=%5B%5D&searchType=ASKAP&project=AS102%20-%20ASKAP%20Pilot%20Survey%20for%20WALLABY&filename=HIPASS%2a_%2a10arc_split - -''' - diff --git a/download_data_casda/casda_download_austin.py b/download_data_casda/casda_download_austin.py deleted file mode 100644 index c65e89b..0000000 --- a/download_data_casda/casda_download_austin.py +++ /dev/null @@ -1,293 +0,0 @@ -#!/usr/bin/env python3 - -''' -Notes: -- Reference link: https://github.com/AusSRC/pipeline_components/blob/main/casda_download/casda_download.py -- Comments added from ChatGPT (07/10/24) - - -''' - -# Provides a way of interacting with the operating system -import os - -# Allows interaction with the Python interpreter -import sys - -# Enables the creation of log messages for tracking events that happen during program execution -import logging - -# Provides methods for parsing JSON (JavaScript Object Notation) data and converting Python objects to JSON format -import json - -# Provides functions for working with URLs, including opening, reading, and parsing URLs -import urllib - -# Enables asynchronous programming allowing for concurrent execution of code without using traditional threading or multiprocessing -import asyncio - -# Provides core functionality for astronomy and astrophysics, such as handling astronomical data, units, and time calculations -import astropy - -# Provides functionality for working with configuration files (typically .ini format), enabling you to read, modify, and write configuration settings -import configparser - -# astroquery is a package for querying astronomical databases -# TapPlus provides an interface for working with Table Access Protocol (TAP) services, which are commonly used to query large astronomical datasets -from astroquery.utils.tap.core import TapPlus - -# Part of astroquery, this module specifically deals with querying and retrieving data from the CASDA (CSIRO ASKAP Science Data Archive) database -from astroquery.casda import Casda - -# Provides a high-level interface for asynchronously executing code using threads or processes, which allows you to execute tasks concurrently -import concurrent.futures - -''' -The logging.basicConfig() function configures the logging system in Python, setting up how log messages will be handled. -stream=sys.stdout: -- This specifies that the log messages will be sent to sys.stdout (i.e., the standard output, typically your terminal or console). - -level=logging.INFO: -- Only log messages with a severity level of INFO and above (i.e., INFO, WARNING, ERROR, CRITICAL) will be processed and shown. -- Lower severity levels like DEBUG will be ignored. - -format='[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s' -- This specifies how each log message will be formatted. -- The format string contains placeholders that are replaced with specific information about the log event. - -''' -logging.basicConfig(stream=sys.stdout, - level=logging.INFO, - format='[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s') - - -# Astropy will not automatically download the IERS data files if they are not present on your system. -astropy.utils.iers.conf.auto_download = False - - -URL = "https://casda.csiro.au/casda_vo_tools/tap" - -WALLABY_QUERY = ( - "SELECT * FROM ivoa.obscore WHERE obs_id IN ($SBIDS) AND " - "dataproduct_type='cube' AND (" - "filename LIKE 'weights.i.%.cube.fits' OR " - "filename LIKE 'image.restored.i.%.cube.contsub.fits')") - -WALLABY_MILKYWAY_QUERY = ( - "SELECT * FROM ivoa.obscore WHERE obs_id IN ($SBIDS) " - "AND dataproduct_type='cube' AND " - "(filename LIKE 'weights.i.%.cube.MilkyWay.fits' OR filename LIKE 'image.restored.i.%.cube.MilkyWay.contsub.fits')" -) - -POSSUM_QUERY = ( - "SELECT * FROM ivoa.obscore WHERE obs_id IN ($SBIDS) AND " - "dataproduct_type='cube' AND (" - "filename LIKE 'image.restored.i.%.contcube.conv.fits' OR " - "filename LIKE 'weights.q.%.contcube.fits' OR " - "filename LIKE 'image.restored.q.%.contcube.conv.fits' OR " - "filename LIKE 'image.restored.u.%.contcube.conv.fits')") - -EMU_QUERY = ( - "SELECT * FROM ivoa.obscore WHERE obs_id IN ($SBIDS) AND ( " - "filename LIKE 'image.i.%.cont.taylor.%.restored.conv.fits' OR " - "filename LIKE 'weights.i.%.cont.taylor%.fits')") - -DINGO_QUERY = ( - "SELECT * FROM ivoa.obscore WHERE obs_id IN ($SBIDS) AND " - "(filename LIKE 'weights.i.%.cube.fits' OR " - "filename LIKE 'image.restored.i.%.cube.contsub.fits' OR " - "filename LIKE 'image.i.%.0.restored.conv.fits')") - -def parse_args(argv): - parser = argparse.ArgumentParser() - - # The add_argument method is to define the command-line arguments the script will accept - # --sbid --output m--project --credentials --manifest - parser.add_argument( - "-s", - "--sbid", - type=str, - required=True, - action='append', - nargs='+', - help="Scheduling block id number.",) - - parser.add_argument( - "-o", - "--output", - type=str, - required=True, - help="Output directory for downloaded files.",) - - parser.add_argument( - "-p", - "--project", - type=str, - required=True, - help="ASKAP project name (WALLABY or POSSUM).",) - - parser.add_argument( - "-c", - "--credentials", - type=str, - required=False, - help="CASDA credentials config file.", - default="./casda.ini",) - - parser.add_argument( - "-m", - "--manifest", - type=str, - required=False, - help="Manifest Output",) - - parser.add_argument( - "-t", "--timeout", - type=int, - required=False, - default=3000, - help="CASDA download file timeout [seconds]") - - # This method parses the list of command-line arguments passed to the function (argv) and returns an args object that contains the parsed values. - args = parser.parse_args(argv) - return args - -''' -- The function tap_query(project, sbid) is designed to generate and execute a TAP (Table Access Protocol) query to retrieve data from a database, -- specifically files related to a given scheduling block ID (sbid) within a specified project (such as "WALLABY", "POSSUM", etc.). -- The function uses the TapPlus class from the astroquery package to perform the query and return the results as an Astropy table. -''' -def tap_query(project, sbid): - """Return astropy table with query result (files to download)""" - - ids = [f"'{str(i)}'" for i in sbid[0]] - - if project == "WALLABY": - logging.info(f"Scheduling block ID: {sbid}") - query = WALLABY_QUERY.replace("$SBIDS", ",".join(ids)) - query = query.replace("$SURVEY", str(project)) - logging.info(f"TAP Query: {query}") - - elif project == "WALLABY_MILKYWAY": - logging.info(f"Scheduling block ID: {sbid}") - query = WALLABY_MILKYWAY_QUERY.replace("$SBIDS", ",".join(ids)) - query = query.replace("$SURVEY", str(project)) - logging.info(f"TAP Query: {query}") - - elif project == "POSSUM": - logging.info(f"Scheduling block ID: {sbid}") - query = POSSUM_QUERY.replace("$SBIDS", ",".join(ids)) - query = query.replace("$SURVEY", str(project)) - logging.info(f"TAP Query: {query}") - - elif project == "DINGO": - logging.info(f"Scheduling block ID: {sbid}") - query = DINGO_QUERY.replace("$SBIDS", ",".join(ids)) - query = query.replace("$SURVEY", str(project)) - logging.info(f"TAP Query: {query}") - - elif project == "EMU": - logging.info(f"Scheduling block ID: {sbid}") - query = EMU_QUERY.replace("$SBIDS", ",".join(ids)) - query = query.replace("$SURVEY", str(project)) - logging.info(f"TAP Query: {query}") - else: - raise Exception('Unexpected project name provided.') - - casdatap = TapPlus(url=URL, verbose=False) - job = casdatap.launch_job_async(query) - res = job.get_results() - logging.info(f"Query result: {res}") - return res - -''' -- The download_file function is designed to download a file from a given URL, save it to a specified output directory, and ensure the file is downloaded completely and correctly. -- The function includes checks for file existence, size validation, and proper error handling. -''' -def download_file(url, check_exists, output, timeout, buffer=4194304): - # Large timeout is necessary as the file may need to be stage from tape - logging.info(f"Requesting: URL: {url} Timeout: {timeout}") - - try: - os.makedirs(output) - except: - pass - - if url is None: - raise ValueError('URL is empty') - - with urllib.request.urlopen(url, timeout=timeout) as r: - filename = r.info().get_filename() - filepath = f"{output}/{filename}" - http_size = int(r.info()['Content-Length']) - if check_exists: - try: - file_size = os.path.getsize(filepath) - if file_size == http_size: - logging.info(f"File exists, ignoring: {os.path.basename(filepath)}") - # File exists and is same size; do nothing - return filepath - except FileNotFoundError: - pass - - logging.info(f"Downloading: {filepath} size: {http_size}") - count = 0 - with open(filepath, 'wb') as o: - while http_size > count: - buff = r.read(buffer) - if not buff: - break - o.write(buff) - count += len(buff) - - download_size = os.path.getsize(filepath) - if http_size != download_size: - raise ValueError(f"File size does not match file {download_size} and http {http_size}") - - logging.info(f"Download complete: {os.path.basename(filepath)}") - - return filepath - -''' -- The provided code defines an asynchronous Python function main that downloads image cubes from CASDA based on observing block IDs provided as command-line arguments -''' -async def main(argv): - """Downloads image cubes from CASDA matching the observing block IDs - provided in the arguments. - - """ - args = parse_args(argv) - res = tap_query(args.project, args.sbid) - logging.info(res) - - # stage - parser = configparser.ConfigParser() - parser.read(args.credentials) - casda = Casda() - casda = Casda(parser["CASDA"]["username"], parser["CASDA"]["password"]) - url_list = casda.stage_data(res, verbose=True) - logging.info(f"CASDA download staged data URLs: {url_list}") - - file_list = [] - with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor: - futures = [] - for url in url_list: - if url.endswith('checksum'): - continue - futures.append(executor.submit(download_file, url=url, check_exists=True, output=args.output, timeout=args.timeout)) - - for future in concurrent.futures.as_completed(futures): - file_list.append(future.result()) - - if args.manifest: - try: - os.makedirs(os.path.dirname(args.manifest)) - except: - pass - - with open(args.manifest, "w") as outfile: - outfile.write(json.dumps(file_list)) - -if __name__ == "__main__": - argv = sys.argv[1:] - asyncio.run(main(argv)) diff --git a/download_data_casda/casda_download_wallaby-hires.py b/download_data_casda/casda_download_wallaby-hires.py index 6a38f8a..cd8b2ff 100644 --- a/download_data_casda/casda_download_wallaby-hires.py +++ b/download_data_casda/casda_download_wallaby-hires.py @@ -155,8 +155,8 @@ async def main(argv): casda = Casda() # casda = Casda(parser["CASDA"]["username"], parser["CASDA"]["password"]) - # casda.login(username=parser["CASDA"]["username"], password=parser["CASDA"]["password"]) - casda.login(username=parser["CASDA"]["username"], store_password=True) + casda.login(username=parser["CASDA"]["username"], password=parser["CASDA"]["password"]) + # casda.login(username=parser["CASDA"]["username"], store_password=True) # Stage the data (retrieve the list of URLs to download) url_list = casda.stage_data(res, verbose=True) diff --git a/download_data_casda/casda_download_wallaby-hires_test.py b/download_data_casda/casda_download_wallaby-hires_test.py deleted file mode 100644 index a198c44..0000000 --- a/download_data_casda/casda_download_wallaby-hires_test.py +++ /dev/null @@ -1,31 +0,0 @@ -# 1) Query: - -# Query that worked: (1 beam) -SELECT * FROM ivoa.obscore -WHERE filename = 'HIPASSJ1318-21_A_beam10_10arc_split.ms.tar' - -# Query that worked (6 beams) -SELECT * FROM ivoa.obscore -WHERE filename LIKE 'HIPASSJ1318-21_%_10arc_split.ms.tar' - -HIPASS_QUERY = ( - "SELECT * FROM ivoa.obscore WHERE " - "filename LIKE 'HIPASSJ1318-21_%_10arc_split.ms.tar'" -) - -HIPASS_QUERY = ( - "SELECT * FROM ivoa.obscore WHERE " - "filename = 'HIPASSJ1318-21_A_beam10_10arc_split.ms.tar'" -) - -# HIPASS Query taking into account the filename -HIPASS_QUERY = ( - "SELECT * FROM ivoa.obscore WHERE " - "filename LIKE ($filename)" -) - -# HIPASS query taking into account the filename -HIPASS_QUERY_TEMPLATE = ( - "SELECT * FROM ivoa.obscore WHERE " - "filename LIKE '%{}%'" -) \ No newline at end of file diff --git a/download_data_casda/tap_query_practice.ipynb b/download_data_casda/tap_query_practice.ipynb deleted file mode 100644 index b636764..0000000 --- a/download_data_casda/tap_query_practice.ipynb +++ /dev/null @@ -1,254 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "309b3852-fe6a-44fc-95f2-190bd45a7165", - "metadata": {}, - "source": [ - "Start date: 08/10/24\n", - "Links from Dave: \n", - "- https://astroquery.readthedocs.io/en/latest/casda/casda.html" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "49ef92e0", - "metadata": {}, - "outputs": [], - "source": [ - "from astroquery.casda import Casda\n", - "from astropy.coordinates import SkyCoord\n", - "from astropy import units as u" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "85fc1a95", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " obs_publisher_did s_ra ... obs_release_date \n", - " deg ... \n", - "------------------- ------------------- ... ------------------------\n", - " cube-1170 333.70448386919 ... 2023-09-01T04:16:51.758Z\n", - "scan-457266-3328493 -26.57452738330125 ... 2024-06-17T07:08:26.494Z\n", - "scan-443110-3314337 -25.864575379354648 ... 2024-06-05T01:12:23.084Z\n", - "scan-501430-3372657 -25.864575379354648 ... 2024-07-24T01:01:21.345Z\n", - " scan-386843-575274 -25.864575379354648 ... 2024-05-06T06:40:57.944Z\n", - "scan-550962-3422189 -25.864575379354648 ... 2024-09-26T03:22:12.727Z\n", - "scan-444262-3315489 -25.864575379354648 ... 2024-06-10T06:49:17.005Z\n", - "scan-457273-3328500 -25.929949863779076 ... 2024-06-17T07:08:26.494Z\n", - "scan-457267-3328494 -25.276376906873345 ... 2024-06-17T07:08:26.494Z\n", - " ... ... ... ...\n", - " cube-24177 341.55322821982 ... 2020-12-04T01:01:29.989Z\n", - " cube-24178 341.55322821982 ... 2020-12-04T01:01:29.989Z\n", - " cube-24179 341.55322821982 ... 2020-12-04T01:01:29.989Z\n", - " cube-24180 341.55322821982 ... 2020-12-04T01:01:29.989Z\n", - " cube-71010 341.5532283333 ... 2021-12-03T02:48:14.613Z\n", - " cube-71433 341.5532283333 ... 2021-12-03T02:48:14.613Z\n", - " cube-650 326.04487794126 ... 2018-05-25T08:22:51.025Z\n", - " cube-39376 319.61500678121 ... 2022-08-18T04:02:29.778Z\n", - " cube-39375 319.61500678121 ... 2022-08-18T04:02:29.778Z\n", - " cube-39374 319.61500678121 ... 2022-08-18T04:02:29.778Z\n", - "Length = 3290 rows\n" - ] - } - ], - "source": [ - "centre = SkyCoord.from_name('NGC 7232')\n", - "result_table = Casda.query_region(centre, radius=30*u.arcmin)\n", - "print(result_table['obs_publisher_did','s_ra', 's_dec', 'obs_release_date']) " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "db605d79-8ac6-4f74-8c61-674380ffb07b", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "5d8b7971-b11e-4271-8541-5d5735930929", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " obs_publisher_did s_ra ... obs_release_date \n", - " deg ... \n", - "------------------- ------------------- ... ------------------------\n", - " cube-1170 333.70448386919 ... 2023-09-01T04:16:51.758Z\n", - "scan-457266-3328493 -26.57452738330125 ... 2024-06-17T07:08:26.494Z\n", - "scan-443110-3314337 -25.864575379354648 ... 2024-06-05T01:12:23.084Z\n", - "scan-501430-3372657 -25.864575379354648 ... 2024-07-24T01:01:21.345Z\n", - " scan-386843-575274 -25.864575379354648 ... 2024-05-06T06:40:57.944Z\n" - ] - } - ], - "source": [ - "public_results = Casda.filter_out_unreleased(result_table)\n", - "print(public_results['obs_publisher_did','s_ra', 's_dec', 'obs_release_date'][:5]) " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "165c71c2-96a4-43b5-8a7e-bfbe10f6d2b7", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a2e6e936-4260-4541-b0ee-c4bed6fac46e", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "3bb3c24a-fa26-4fe8-931f-cbafbe78fdc8", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING: No password was found in the keychain for the provided username. [astroquery.query]\n", - "WARNING: You may be using an ipython notebook: the password form will appear in your terminal. [astroquery.query]\n" - ] - }, - { - "name": "stdin", - "output_type": "stream", - "text": [ - "gayatri.aniruddha@uwa.edu.au, enter your password:\n", - " ········\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO: Authenticating gayatri.aniruddha@uwa.edu.au on CASDA ... [astroquery.casda.core]\n", - "INFO: Authentication successful! [astroquery.casda.core]\n" - ] - } - ], - "source": [ - "from astroquery.casda import Casda\n", - "casda = Casda()\n", - "casda.login(username='gayatri.aniruddha@uwa.edu.au')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bce4493f-1f1a-4c35-bad9-dfa495452d1a", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 37, - "id": "35c253fa-29b3-4672-bf7f-d955c6dfad0e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO: Authenticating gayatri.aniruddha@uwa.edu.au on CASDA ... [astroquery.casda.core]\n", - "INFO: Authentication successful! [astroquery.casda.core]\n" - ] - } - ], - "source": [ - "from astroquery.casda import Casda\n", - "casda = Casda()\n", - "casda.login(username='gayatri.aniruddha@uwa.edu.au',store_password=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "20d7000d-e8c7-41e5-8d16-79deaaa112a3", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fe857bb7-eef4-4c36-9ef7-8757b852f122", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "82fb409f-0499-413c-8ffa-4ce4a6306a25", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "08cf7d98-ecf4-4065-b6b0-a1a464c72a61", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "87e19406-9cce-45cf-8950-dd4616c7c565", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "db328b12-5c11-4034-82e4-24054ee34d94", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.3" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -}