115115
116116
117117"""
118- import os
119- from collections import OrderedDict
120118from datetime import timedelta
121119from pathlib import Path
122120from typing import List , Sequence , Tuple , Dict , Any , Union
123121
124122import numpy as np
125123import tfs
126124from generic_parser import DotDict
127- from generic_parser .entrypoint_parser import EntryPointParameters , entrypoint , save_options_to_config
125+ from generic_parser .entrypoint_parser import EntryPointParameters , entrypoint
128126from numpy .typing import ArrayLike
129127from tfs .frame import TfsDataFrame
130128
131- from omc3 .definitions import formats
132129from omc3 .definitions .constants import PLANES
133130from omc3 .tune_analysis import fitting_tools , kick_file_modifiers , timber_extract
134- from omc3 .tune_analysis .bbq_tools import OutlierFilterOpt , MinMaxFilterOpt
131+ from omc3 .tune_analysis .bbq_tools import OutlierFilterOpt , MinMaxFilterOpt , FilterOpts
135132from omc3 .tune_analysis .constants import (
136133 get_bbq_col ,
137134 get_bbq_out_name ,
138135 get_kick_out_name ,
139- get_mav_col ,
140- get_timber_bbq_key , INPUT_KICK , INPUT_PREVIOUS , CORRECTED ,
136+ get_timber_bbq_key ,
137+ get_natq_err_col ,
138+ INPUT_KICK , INPUT_PREVIOUS , CORRECTED ,
141139)
142140from omc3 .tune_analysis .kick_file_modifiers import (
143141 read_timed_dataframe ,
@@ -266,7 +264,8 @@ def analyse_with_bbq_corrections(opt: DotDict) -> Tuple[TfsDataFrame, TfsDataFra
266264
267265 opt , filter_opt = _check_analyse_opt (opt )
268266 kick_df , bbq_df = get_kick_and_bbq_df (kick = opt .kick , bbq_in = opt .bbq_in ,
269- beam = opt .beam , filter_opt = filter_opt , output = opt .output )
267+ beam = opt .beam ,
268+ filter_opt = filter_opt )
270269
271270 kick_plane = opt .plane
272271
@@ -277,23 +276,34 @@ def analyse_with_bbq_corrections(opt: DotDict) -> Tuple[TfsDataFrame, TfsDataFra
277276 kick_df = double_action_analysis (kick_df , opt .detuning_order , corrected )
278277
279278 if opt .output :
280- LOG .info (f"Writing kick data to file in directory '{ opt .output .absolute ()} '" )
281- opt .output .mkdir (parents = True , exist_ok = True )
282- write_timed_dataframe (opt .output / get_kick_out_name (), kick_df )
283-
279+ _write_dataframes (opt .output , kick_df , bbq_df )
284280 return kick_df , bbq_df
285281
286282
287283def get_kick_and_bbq_df (kick : Union [Path , str ], bbq_in : Union [Path , str ],
288- beam : int = None , filter_opt = None ,
289- output : Path = None
284+ beam : int = None ,
285+ filter_opt : FilterOpts = None ,
290286 ) -> Tuple [tfs .TfsDataFrame , tfs .TfsDataFrame ]:
291287 """Load the input data."""
292288 bbq_df = None
293289 if bbq_in is not None and bbq_in == INPUT_PREVIOUS :
290+ # NOTE: this is not the same as the "previous BBQ data" option in the GUI.
291+ # That one just uses the previous bbq_ampdet.tfs file (loaded in the "else" below).
292+ # The use-case for the INPUT_PREVIOUS option here is,
293+ # that you can modify the kick_ampdet_xy file manually (e.g. removing kicks)
294+ # and run the fitting on the new data again,
295+ # without having to touch the whole BBQ stuff again (as the values are already in the file).
296+ # Tips:
297+ # - Remove full columns to get rid of the whole kick
298+ # - Add NaNs into NATQ columns you want to ignore (in case you want to keep the other plane for this kick)
299+ # - Add NaNs to the ERRNATQ columns if you want to plot the point (w/o error bars) but not use it for fit
294300 LOG .debug ("Getting data from previous ampdet kick file" )
295301 kick_df = read_timed_dataframe (Path (kick ) / get_kick_out_name ())
296302 kick_df .headers = {k : v for k , v in kick_df .headers .items () if not k .startswith ("ODR_" )}
303+
304+ # redo the corrected columns, so you only need to add NaNs into the NATQ columns
305+ LOG .debug ("Adding corrected natural tunes and stdev to kick data" )
306+ kick_df = kick_file_modifiers .add_corrected_natural_tunes (kick_df )
297307 else :
298308 LOG .debug ("Getting data from kick files" )
299309 kick_df = read_two_kick_files_from_folder (kick )
@@ -307,15 +317,6 @@ def get_kick_and_bbq_df(kick: Union[Path, str], bbq_in: Union[Path, str],
307317 LOG .debug ("Adding corrected natural tunes and stdev to kick data" )
308318 kick_df = kick_file_modifiers .add_corrected_natural_tunes (kick_df )
309319
310- if output :
311- LOG .info (f"Writing BBQ data to file in directory '{ output .absolute ()} '" )
312- try :
313- window = filter_opt .window
314- except AttributeError :
315- window = filter_opt [0 ].window
316-
317- x_interval = get_approx_bbq_interval (bbq_df , kick_df .index , window )
318- write_timed_dataframe (output / get_bbq_out_name (), bbq_df .loc [x_interval [0 ]: x_interval [1 ]])
319320 return kick_df , bbq_df
320321
321322
@@ -419,7 +420,7 @@ def get_approx_bbq_interval(
419420# Private Functions ------------------------------------------------------------
420421
421422
422- def _check_analyse_opt (opt : DotDict ):
423+ def _check_analyse_opt (opt : DotDict ) -> Tuple [ DotDict , FilterOpts ] :
423424 """Perform manual checks on opt-sturcture."""
424425 LOG .debug ("Checking Options." )
425426
@@ -542,6 +543,15 @@ def _get_ampdet_data_as_array(data: Dict[Any, AmpDetData], column: str) -> Array
542543 return np .vstack ([getattr (d , column ) for d in data .values ()])
543544
544545
546+ def _write_dataframes (output : Path , kick_df : TfsDataFrame , bbq_df : TfsDataFrame ):
547+ LOG .info (f"Writing kick data to file in directory '{ output .absolute ()} '" )
548+ output .mkdir (parents = True , exist_ok = True )
549+ write_timed_dataframe (output / get_kick_out_name (), kick_df )
550+ if bbq_df is not None :
551+ LOG .info (f"Writing BBQ data to file in directory '{ output .absolute ()} '" )
552+ write_timed_dataframe (output / get_bbq_out_name (), bbq_df )
553+
554+
545555# Script Mode ##################################################################
546556
547557
0 commit comments