From 8b193da9a875b063352392b4f8d047c76b8c81a1 Mon Sep 17 00:00:00 2001 From: Laura Toribio San Cipriano Date: Thu, 25 Apr 2024 14:59:38 +0000 Subject: [PATCH] Add notebooks SITCOM-1223 --- ..._discharge_vs._Acceleration_profiles.ipynb | 612 ++++++++++++++++++ 1 file changed, 612 insertions(+) create mode 100644 notebooks/SITCOM-1223-TMA_Capacitor_Bank_discharge_vs._Acceleration_profiles.ipynb diff --git a/notebooks/SITCOM-1223-TMA_Capacitor_Bank_discharge_vs._Acceleration_profiles.ipynb b/notebooks/SITCOM-1223-TMA_Capacitor_Bank_discharge_vs._Acceleration_profiles.ipynb new file mode 100644 index 0000000..22b8a33 --- /dev/null +++ b/notebooks/SITCOM-1223-TMA_Capacitor_Bank_discharge_vs._Acceleration_profiles.ipynb @@ -0,0 +1,612 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a6db2928-1a8c-4c56-b823-d75d65991952", + "metadata": {}, + "source": [ + "# TMA Capacitor Bank discharge vs. Acceleration profiles \n", + "# [SITCOM-1223]" + ] + }, + { + "cell_type": "markdown", + "id": "7ff13bd8-b9ff-458a-a6c0-ccbd53a7bc2b", + "metadata": {}, + "source": [ + "Laura Toribio San Cipriano\n", + "\"Feb. 14, 2024\"" + ] + }, + { + "cell_type": "markdown", + "id": "7c8f1ee3-802f-4c11-9d41-5b182cc76481", + "metadata": {}, + "source": [ + "https://jira.lsstcorp.org/browse/SITCOM-1223" + ] + }, + { + "cell_type": "markdown", + "id": "b2b1dc88-117b-4e40-a170-dd915bd48c62", + "metadata": {}, + "source": [ + "**Description:**\n", + "Continue the analysis started in SITCOM-1146. Based on the input from a team review, focusing on aspects below. Another ticket opened to investigate current draw profiles.\n", + "\n", + "- Relationship of min power supply voltage and distance of slew\n", + "- Explore when Az and El moved at same time, rather than separately\n", + "- Look at Azimuth acceleration vs. power supply voltage\n", + "\n", + "Results and analysis to be added to SITCOMTN-110" + ] + }, + { + "cell_type": "markdown", + "id": "7036903c-829f-4bb2-b01a-fa131a7afeec", + "metadata": {}, + "source": [ + "### Setup" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "19d58718-e810-40ff-acda-945b6cbd212a", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "%matplotlib widget\n", + "%load_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "66513868-8595-4eac-9346-f1037aa3684d", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from astropy.io import fits\n", + "\n", + "from lsst_efd_client import EfdClient, resample\n", + "from lsst.summit.utils.tmaUtils import TMAEventMaker, TMAState\n", + "\n", + "from astropy.time import Time, TimeDelta\n", + "from astropy.table import Table\n", + "from scipy.interpolate import UnivariateSpline" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cf0c56c6-dbfe-4a93-80c4-2cdfa138099d", + "metadata": {}, + "outputs": [], + "source": [ + "client = EfdClient('usdf_efd')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "837ad61c-b26c-4178-b788-f24a401d8a40", + "metadata": {}, + "outputs": [], + "source": [ + "tma_power_topic = 'lsst.sal.MTMount.mainPowerSupply'\n", + "tma_el_topic = 'lsst.sal.MTMount.elevation'\n", + "tma_az_topic = 'lsst.sal.MTMount.azimuth'" + ] + }, + { + "cell_type": "markdown", + "id": "7548b05f-1d0d-4c5a-b58e-66bfd6e9ff43", + "metadata": {}, + "source": [ + "### Get Data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "45291eff-5742-483e-aeba-b48cef30f7ec", + "metadata": {}, + "outputs": [], + "source": [ + "obs_days = [20240220, 20240221]# [20231211, 20231212, 20231213, 20231214, 20231215, 20231218]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6040f80f-f9c7-4b6d-b866-a37a7d41a243", + "metadata": {}, + "outputs": [], + "source": [ + "def get_events(dayObs):\n", + " \"\"\"\n", + " Identify slew events for a given dayObs\n", + " \"\"\"\n", + " eventMaker = TMAEventMaker()\n", + " events = eventMaker.getEvents(dayObs)\n", + " \n", + " # Get lists of slew and track events\n", + " slews = [e for e in events if e.type == TMAState.SLEWING]\n", + " tracks = [e for e in events if e.type == TMAState.TRACKING]\n", + " print(f\"{dayObs}: Found {len(slews)} slews and {len(tracks)} tracks\")\n", + " return slews" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34564d44-e718-4b2b-b18a-2bb81eb34f05", + "metadata": {}, + "outputs": [], + "source": [ + "def get_acc_jerk(time, velocity):\n", + " \"\"\"\n", + " From velocity data, calculate acceleration and jerk\n", + " \"\"\"\n", + " try:\n", + " smoothing_factor=0.2\n", + " kernel_size = 5\n", + " kernel = np.ones(kernel_size) / kernel_size\n", + " \n", + " VelSpline = UnivariateSpline(time, velocity, s=0)\n", + " smoothedVel = np.convolve(VelSpline(time), kernel, mode='same')\n", + " VelSpline = UnivariateSpline(time, smoothedVel, s=smoothing_factor)\n", + " \n", + " AccSpline = VelSpline.derivative(n=1)\n", + " smoothedAcc = np.convolve(AccSpline(time), kernel, mode='same')\n", + " AccSpline = UnivariateSpline(time, smoothedAcc, s=smoothing_factor)\n", + " \n", + " JerkSpline = AccSpline.derivative(n=1) \n", + "\n", + " return VelSpline(time), AccSpline(time), JerkSpline(time)\n", + " except:\n", + " return False, False, False" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1cca7704-b62d-4d98-92bc-d114f50b528a", + "metadata": {}, + "outputs": [], + "source": [ + "async def data_per_slew(i, slew, debug=False):\n", + " \"\"\"\n", + " get TMA velocity data and power data for a given slew.\n", + "\n", + " Calculate maximum velocity, acceleration and jerk values and minimum power draw\n", + " \"\"\"\n", + " data = [i, slew.dayObs, slew.duration, slew.begin, slew.end]\n", + " power_df = await client.select_time_series(tma_power_topic, '*', slew.begin, slew.end)\n", + " data.append(np.min(power_df.powerSupplyVoltage))\n", + " \n", + " az = await client.select_time_series(tma_az_topic, ['*'], slew.begin, slew.end)\n", + " el = await client.select_time_series(tma_el_topic, ['*'], slew.begin, slew.end)\n", + " \n", + " AzBegin = az.actualPosition.iloc[0]\n", + " AzEnd = az.actualPosition.iloc[-1]\n", + " ElBegin = el.actualPosition.iloc[0]\n", + " ElEnd = el.actualPosition.iloc[-1]\n", + " \n", + " AzVel, AzAcc, AzJerk = get_acc_jerk(az.timestamp, az.actualVelocity)\n", + " ElVel, ElAcc, ElJerk = get_acc_jerk(el.timestamp, el.actualVelocity)\n", + "\n", + " #theta = calculate_angular_distance(ElBegin, AzBegin, ElEnd, AzEnd)\n", + " for var in [AzVel, AzAcc, AzJerk, ElVel, ElAcc, ElJerk, AzBegin, AzEnd, ElBegin, ElEnd]: #, theta\n", + " data.append(np.max(np.abs(var)))\n", + " if debug:\n", + " return az, el, power_df, data\n", + " else:\n", + " return data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cda71afb-bd9a-4c20-9336-e1f928ec5133", + "metadata": {}, + "outputs": [], + "source": [ + "Data = []\n", + "failed = []\n", + "data_names = ['slew_id','dayobs','duration','begin','end','min_power','az_max_vel','az_max_acc','az_max_jerk','el_max_vel','el_max_acc','el_max_jerk', 'az_pos_begin', 'az_pos_end', 'el_pos_begin', 'el_pos_end'] #, 'dis_slew'\n", + "for dayObs in obs_days:\n", + " try:\n", + " slews = get_events(dayObs)\n", + " except:\n", + " print(dayObs)\n", + " for i, slew in enumerate(slews):\n", + " try:\n", + " d = await data_per_slew(i, slew)\n", + " Data.append(d)\n", + " except Exception as e:\n", + " failed.append(i)\n", + " #print(i, e)\n", + "df = pd.DataFrame(np.vstack(Data),columns=data_names)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "36a0fbcc-5d88-4c1a-afc6-ecef8abba4a7", + "metadata": {}, + "outputs": [], + "source": [ + "#Remove extreme outliers\n", + "df = df[(df.el_max_jerk < 100)&(df.duration<3000)]" + ] + }, + { + "cell_type": "markdown", + "id": "61ac92fc-1c16-4102-9b08-094525142f7e", + "metadata": {}, + "source": [ + "### Analysis" + ] + }, + { + "cell_type": "markdown", + "id": "406fed55-1613-4a73-a6c3-89441603d876", + "metadata": {}, + "source": [ + "#### Relationship of min power supply voltage and distance of slew" + ] + }, + { + "cell_type": "markdown", + "id": "ab72bc6c-dd0c-46fa-bb6d-89179d1a7bbf", + "metadata": {}, + "source": [ + "We have investigated the relationship between the minimum power supply voltage and the distance of slew. \n", + "\n", + "Initially, we attempted to calculate the slew distance using the formula for angular distance. In this analysis, we included an explanation of the formula and the function `calculate_angular_distance`, although ultimately, it was not used due to errors it generated.\n", + "\n", + "Therefore, to analyze the slew distance, we calculated the azimuth and elevation distances. For each observation day, we examined the scatter of the differences in azimuth and elevation at the start and end of the slew with their respective minimum supply power voltage. Additionally, we created histograms of these differences in the slew and of the minimum supply power voltage used.\n" + ] + }, + { + "cell_type": "markdown", + "id": "d18c07d6-f9b0-429e-9e97-133f6dbb33fc", + "metadata": {}, + "source": [ + "##### Angular Distance Formula\n", + "\n", + "WARNING: We have not been able to measure the distance in this way because the angles are too small and it gave us an error in the calculation.\n", + "\n", + "The formula used to calculate the angular distance between two points on the celestial sphere is based on the Spherical Law of Cosines.\n", + "\n", + "\\[ \\cos(\\theta) = \\sin(\\text{elevation}_1) \\sin(\\text{elevation}_2) + \\cos(\\text{elevation}_1) \\cos(\\text{elevation}_2) \\cos(\\text{azimuth}_1 - \\text{azimuth}_2) \\]\n", + "\n", + "Where:\n", + "- \\( \\theta \\) is the angular distance between the two points on the celestial sphere.\n", + "- \\( \\text{elevation}_1 \\) and \\( \\text{elevation}_2 \\) are the elevations of the two points, respectively, measured in radians.\n", + "- \\( \\text{azimuth}_1 \\) and \\( \\text{azimuth}_2 \\) are the azimuths of the two points, respectively, measured in radians." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43ae3b6b-ea9b-4a01-b5b9-c7887e29369b", + "metadata": {}, + "outputs": [], + "source": [ + "# Function to calculate the angular distance between two points in the celestial sphere\n", + "def calculate_angular_distance(el_start, az_start, el_end, az_end):\n", + "\n", + " # Convert elevation and azimuth to radians\n", + " el_start_rad = np.radians(el_start)\n", + " az_start_rad = np.radians(az_start)\n", + " el_end_rad = np.radians(el_end)\n", + " a_end_rad = np.radians(az_end)\n", + " \n", + " # Calculate the angular distance using the cosine formula\n", + " cos_theta = np.sin(el_start_rad) * np.sin(el_end_rad) + np.cos(el_start_rad) * np.cos(el_end_rad) * np.cos(az_start_rad - az_end_rad)\n", + " \n", + " # Calculate the angle (in radians) between the two points\n", + " theta_rad = np.arccos(cos_theta)\n", + "\n", + " # Convert from radians to degrees and return the result\n", + " return np.degrees(theta_rad)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4a0fdf1d-fca1-40e4-883d-e85c72f27dad", + "metadata": {}, + "outputs": [], + "source": [ + "def plot_spv_vs_dist(df_, title_date, name):\n", + " fig, (ax1) = plt.subplots(figsize=(8, 4))\n", + "\n", + " # Scatter plot of slew distances vs. min_power\n", + " ax1.plot((df_.az_pos_begin - df_.az_pos_end), df_.min_power, 'x', color='C0', label='az')\n", + " ax1.plot((df_.el_pos_begin - df_.el_pos_end), df_.min_power, 'x', alpha=0.7, color='C1', label='el')\n", + " ax1.axhline(575, ls='--', c='k',label='voltage drop limit')\n", + " ax1.legend()\n", + " ax1.set_xlabel('Slew distances (az/el)')\n", + " ax1.set_ylabel('min supplyPowerVoltage (V)')\n", + " ax1.set_title(f'Min. TMA voltage vs. distance of slew for {title_date}')\n", + "\n", + " fig2, (ax2, ax3) = plt.subplots(1, 2, figsize=(12, 4))\n", + " # Histogram of absolute values of position differences\n", + " ax2.hist(df_.az_pos_begin - df_.az_pos_end, color='C0', label='az')\n", + " ax2.hist(df_.el_pos_begin - df_.el_pos_end, color='C1', alpha=0.7, label='el')\n", + " ax2.legend()\n", + " ax2.set_xlabel('Slew distances (az/el)')\n", + " ax2.set_ylabel('Frequency')\n", + " ax2.set_title(f'Slew distance Histogram for {title_date}')\n", + " \n", + " # Histogram of min_power\n", + " ax3.hist(df_.min_power, bins=20, color='C0', edgecolor='black', alpha=0.5)\n", + " ax3.axvline(575, ls='--', c='k', label='voltage drop limit')\n", + " ax3.legend()\n", + " ax3.set_xlabel('min supplyPowerVoltage (V)')\n", + " ax3.set_ylabel('Frequency')\n", + " ax3.set_title(f'Min. TMA voltage histogram for {title_date}')\n", + " \n", + " plt.tight_layout()\n", + " plt.show()\n", + " plt.savefig(f'{name}.png')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d06aad36-444a-4edc-bbc7-84e8146cba70", + "metadata": {}, + "outputs": [], + "source": [ + "for dayObs in np.unique(df.dayobs):\n", + " df_ = df[df.dayobs == dayObs]\n", + " plot_spv_vs_dist(df_, dayObs,'tma_perf_feb_2024')" + ] + }, + { + "cell_type": "markdown", + "id": "a190b326-acf8-41ef-8970-af50efae21aa", + "metadata": {}, + "source": [ + "#### Explore when Az and El moved at same time, rather than separately" + ] + }, + { + "cell_type": "markdown", + "id": "35bc3c1f-1d9c-4a08-910f-852c73204a16", + "metadata": {}, + "source": [ + "We are going to analyze the data for different days to identify instances when the telescope moves simultaneously in both azimuth and elevation.\n", + "\n", + "To accomplish this, we'll initially compare the *timestamp* at the beginning and end of each slew for both azimuth and elevation.\n", + "\n", + "We've categorized our observations into two groups: instances where the telescope moves in azimuth and elevation simultaneously, and instances where it doesn't.\n", + "\n", + "We observed that in all cases, the start and end times of the movements in azimuth and elevation were different. However, upon closer examination, we found that these differences were consistently minimal, typically less than 0.1 seconds." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18daad65-ab85-49be-b6b3-546a8dfd2faa", + "metadata": {}, + "outputs": [], + "source": [ + "def move_az_el(az, el):\n", + " if not az.empty and not el.empty:\n", + " init = az.timestamp.iloc[0] == el.timestamp.iloc[0]\n", + " end = az.timestamp.iloc[-1] == el.timestamp.iloc[-1]\n", + " return init, end\n", + " else:\n", + " # Empty Data\n", + " return False, False" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "90aaf540-dbb5-4356-a1a4-72faa2f71780", + "metadata": {}, + "outputs": [], + "source": [ + "def plot_az_el_slew_analysis(dayObs, simultaneous_movements, No_simultaneous_movements, init_diffs, end_diffs):\n", + " fig, axs = plt.subplots(1, 2, figsize=(10, 5))\n", + "\n", + " labels = ['At same time', 'No Simultaneous']\n", + " counts = [len(simultaneous_movements), len(No_simultaneous_movements)]\n", + "\n", + " axs[0].bar(labels, counts)\n", + " axs[0].set_title(f\"Az and El moved at same time for: {dayObs}\")\n", + " axs[0].set_xlabel('Movement Type')\n", + " axs[0].set_ylabel('Num of slews')\n", + "\n", + " # Values None\n", + " init_diffs = [diff for diff in init_diffs if diff is not None]\n", + " end_diffs = [diff for diff in end_diffs if diff is not None]\n", + "\n", + " axs[1].hist(init_diffs, alpha=0.5, label='Init Difference')\n", + " axs[1].hist(end_diffs, alpha=0.5, label='End Difference')\n", + " axs[1].set_title(f\"Time Differences at Slew Start and End for: {dayObs}\")\n", + " axs[1].set_xlabel('Time Difference (s)')\n", + " axs[1].set_ylabel('Frequency')\n", + " axs[1].legend()\n", + "\n", + " plt.tight_layout()\n", + " plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "47d51210-38b3-4839-ab3a-2a7b9fe35d62", + "metadata": {}, + "outputs": [], + "source": [ + "for dayObs in obs_days:\n", + " simultaneous_movements = [] # Save slews with simultaneous movements in az and el.\n", + " No_simultaneous_movements = [] # Save slews with NO simultaneous movements in az and el.\n", + " init_diffs = [] # Save difference in time (s) of az and el in the start of the slews.\n", + " end_diffs = [] # Save difference in time (s) of az and el in the end of the slews.\n", + " try:\n", + " slews = get_events(dayObs)\n", + " except:\n", + " print(dayObs)\n", + " for i, slew in enumerate(slews):\n", + " az = await client.select_time_series(tma_az_topic, ['*'], slew.begin, slew.end)\n", + " el = await client.select_time_series(tma_el_topic, ['*'], slew.begin, slew.end)\n", + " init, end = move_az_el(az, el)\n", + " if init and end:\n", + " simultaneous_movements.append(i)\n", + " else:\n", + " No_simultaneous_movements.append(i)\n", + " az_diff = az.timestamp.iloc[0] - el.timestamp.iloc[0] if not az.empty and not el.empty else None\n", + " el_diff = az.timestamp.iloc[-1] - el.timestamp.iloc[-1] if not az.empty and not el.empty else None\n", + " init_diffs.append(az_diff)\n", + " end_diffs.append(el_diff)\n", + " \n", + " plot_az_el_slew_analysis(dayObs, simultaneous_movements, No_simultaneous_movements, init_diffs, end_diffs)\n" + ] + }, + { + "cell_type": "markdown", + "id": "1bb5a617-fc34-48c3-baed-5cbe5b326fb3", + "metadata": {}, + "source": [ + "#### Look at Azimuth acceleration vs. power supply voltage" + ] + }, + { + "cell_type": "markdown", + "id": "8ead846c-784f-44c3-bee3-ff6221753cbe", + "metadata": {}, + "source": [ + "We have analyzed the relationship between velocity and mass acceleration with respect to the minimum supply power voltage, as well as the slew distance for azimuth. \n", + "\n", + "Subsequently, we selected those slews with a supply power voltage lower than 575 (V) and analyzed the slew distance.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "00664f30-2a8e-43b5-8b1b-1ba0150b3d8f", + "metadata": {}, + "outputs": [], + "source": [ + "def plots_spv_vs_az(df_, title_date,name):\n", + " fig, (ax1, ax2, ax3) = plt.subplots(1,3, sharey=True, figsize=(12, 4))\n", + "\n", + " ax1.plot(df_.az_max_vel, df_.min_power,'x',label='azVel')\n", + " #ax1.plot(df_.el_max_vel, df_.min_power,'x', label='elVel')\n", + " ax1.axhline(575, ls='--', c='k',label='voltage drop limit')\n", + " ax1.legend()\n", + " #ax1.set_xlim(-1,12)\n", + " ax1.set_xlabel('max Velocity (m/s)')\n", + " ax1.set_ylabel('min supplyPowerVoltage (V)')\n", + "\n", + " ax2.plot(df_.az_max_acc, df_.min_power,'x',label='azAcc')\n", + " #ax2.plot(df_.el_max_acc, df_.min_power,'x',label='elAcc')\n", + " ax2.axhline(575, ls='--', c='k',label='voltage drop limit')\n", + " ax2.legend()\n", + " #ax2.set_xlim(-1,25)\n", + " ax2.set_xlabel('max Acceleration $(m/s^{2})$')\n", + " #ax2.set_ylabel('min supplyPowerVoltage (V)')\n", + " \n", + " ax3.plot((df_.az_pos_begin - df_.az_pos_end), df_.min_power,'x',label='azSlewDis')\n", + " #ax3.plot(df_.el_max_jerk, df_.min_power,'x', label='elJerk')\n", + " ax3.axhline(575, ls='--', c='k',label='voltage drop limit')\n", + " ax3.legend()\n", + " #ax3.set_xlim(-100,800)\n", + " ax3.set_xlabel('Slew distances')\n", + " #ax3.set_ylabel('min supplyPowerVoltage (V)')\n", + " \n", + " fig.suptitle(f'Min. TMA voltage vs. TMA Performance for {title_date}')\n", + " fig.tight_layout()\n", + " plt.savefig(f'{name}.png')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9d2d6156-621d-4cf3-b5c4-f6b409cbf945", + "metadata": {}, + "outputs": [], + "source": [ + "def plots_az(df_, title_date,name):\n", + " df_ = df_[(df_.min_power<575)]\n", + " \n", + " fig, (ax1, ax2) = plt.subplots(1, 2, sharey=False, figsize=(12, 4))\n", + " \n", + " ax1.plot((df_.az_pos_begin - df_.az_pos_end), df_.min_power,'x',label='azSlewDis for Min. Power < 575V')\n", + " ax1.axhline(575, ls='--', c='k',label='voltage drop limit')\n", + " ax1.legend()\n", + " ax1.set_xlabel('Slew distances')\n", + " ax1.set_ylabel('min supplyPowerVoltage (V)')\n", + "\n", + " \n", + " bins = np.linspace(-150, +150, 25)\n", + " ax2.hist(df_.az_pos_begin - df_.az_pos_end, alpha=0.5, bins=bins, color='C0')\n", + " ax2.hist(df_.az_pos_begin - df_.az_pos_end, alpha=0.7, bins=bins, label='Min. Power < 575V') \n", + " ax2.set_xlabel('Slew distances')\n", + " ax2.set_ylabel('Azimuth')\n", + "\n", + " \n", + " fig.suptitle(f'Min. TMA voltage vs. TMA Performance for {title_date} for min_power<575')\n", + " fig.tight_layout()\n", + " plt.savefig(f'{name}.png')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "193195a1-a928-4929-9fc6-9dedb5a9ba05", + "metadata": {}, + "outputs": [], + "source": [ + "for dayObs in np.unique(df.dayobs):\n", + " df_ = df[df.\n", + " dayobs == dayObs]\n", + " plots_spv_vs_az(df_, dayObs,f'tma_perf_{dayObs}')\n", + " plots_az(df_, dayObs,f'tma_perf_{dayObs}')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "593886d5-ce5f-41a6-89b7-6635d2e07e41", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "LSST", + "language": "python", + "name": "lsst" + }, + "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.11.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}