-
Notifications
You must be signed in to change notification settings - Fork 10
Adding the KMOD summary outputs #560
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…to kmod_tabsum_import
|
The output .txt table for the Logbook looks like this without Tabulate package |
Coverage reportClick to see where and how coverage changed
This report was generated by python-coverage-comment-action |
||||||||||||||||||||||||
fsoubelet
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR Mattia, this is going to be useful to have.
I left comments here and there about inconsistencies / code clarity etc. See below.
One thing I'm wondering is: could this be a stand-alone script? And then it could be run on previous folders with kmod measurements from before we had it (and the relevant part just imported and called into kmob_importer.py)?
| # return [round(bstar, 3) for bstar in df_model.loc[ip, [f"{BETA}X", f"{BETA}Y"]]] | ||
| return df_model.loc[ip, [f"{BETA}X", f"{BETA}Y"]].tolist() | ||
|
|
||
| def import_kmod_summary_table( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This writes out things so the naming feels off. Maybe something like output_kmod_summary_tables?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realize import_kmod_data suffers the same problem. We should look to fix that as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(removed - updated below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import_kmod_data makes a bit more sense, because it is importing it into the omc3 analysis folder in the same format as the other files there. Whereas this function really only outputs some text files, which actually do not really need to go into the omc3 results folder. But if there is a good naming suggestion, I am not strictly against renaming the import-data function as well.
|
|
||
| def import_kmod_summary_table( | ||
| meas_paths: Sequence[Path | str], | ||
| averaged_meas_paths: Sequence[tfs.TfsDataFrame], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Above at function call this is passed as averaged_results which is definitely not a Sequence[tfs.TfsDataFrame].
| """ | ||
| Write the KMOD summary table from each results.tfs file. | ||
| It writes down the following files for each beam: | ||
| {beam}_kmod_sum_X.tfs: BETSTARX, ERRBETSTARX, BETWAISTX, ERRBETWAISTX, WAISTX, ERRWAISTX. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| {beam}_kmod_sum_X.tfs: BETSTARX, ERRBETSTARX, BETWAISTX, ERRBETWAISTX, WAISTX, ERRWAISTX. | |
| B{beam}_kmod_sum_X.tfs: BETSTARX, ERRBETSTARX, BETWAISTX, ERRBETWAISTX, WAISTX, ERRWAISTX. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
none of the filenames here are correct actually anyway. There is no X/Y it's all in one file.
sum is actually summary and tables is summary_logbook. I prefer tables though.
And make them all lower-case.
| Write the KMOD summary table from each results.tfs file. | ||
| It writes down the following files for each beam: | ||
| {beam}_kmod_sum_X.tfs: BETSTARX, ERRBETSTARX, BETWAISTX, ERRBETWAISTX, WAISTX, ERRWAISTX. | ||
| {beam}_kmod_sum_X.tfs: BETSTARY, ERRBETSTARY, BETWAISTY, ERRBETWAISTY, WAISTY, ERRWAISTY. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| {beam}_kmod_sum_X.tfs: BETSTARY, ERRBETSTARY, BETWAISTY, ERRBETWAISTY, WAISTY, ERRWAISTY. | |
| B{beam}_kmod_sum_Y.tfs: BETSTARY, ERRBETSTARY, BETWAISTY, ERRBETWAISTY, WAISTY, ERRWAISTY. |
| return df_x, df_y | ||
|
|
||
| grouped = {beam: [] for beam in beams} | ||
| for elem in meas_paths: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer representative variable names. This elem is a path
| """ | ||
|
|
||
| if not av_res_flag: | ||
| file_name = data_sngl_file_raw.parent.parent.name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not going to work is data_sngl_file_raw is a str, which the type hint says is accepted.
| f.write("\n".join(txt_output)) | ||
| tfs.write(output_dir/f"{beam}_kmod_summary.tfs", big_df) | ||
|
|
||
| LOG.info('KMOD summary outputs correctly saved.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| LOG.info('KMOD summary outputs correctly saved.') | |
| LOG.info(f"KMOD summary outputs saved at {output_dir/f'{beam}_kmod_summary.tfs'}") |
even better is the full output path is stored in a variable before
| lumi_filename = _get_lumi_filename(betas, ip_a=ips[0], ip_b=ips[1]) | ||
| assert (average_dir / lumi_filename).exists() | ||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for this line
| lumi_filename = _get_lumi_filename(betas, ip_a=ips[0], ip_b=ips[1]) | ||
| assert (average_dir / lumi_filename).exists() | ||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add a little check that the written files are as expected?
JoschD
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few comments, but my main point is also, that this should be a standalone script, in case someone only wants the table without importing it anywhere.
When refactoring, also separate the output from the reading/transforming. There should be one function that creates the tables and simply returns them. Then another funtion/outer function that writes them out.
In my opinion the script/main function of the script should also have the following parameters:
- outputdir -> optional, write the files ou (always return the tables)
- average -> true/false, calls the functions to average the data (could also be
boolean | path-to-the-file | averaged-dataframes) - logbook -> optional, specify a logbook (LHC_OMC, LHC_OP, true->LHC_OMC) uses the logbook uploader to create a new logbook entry.
And then you can import the function here and re-use it to create the table automatically on import.
When putting it into another script: consider which parts might benefit from being in their own little function as well, to make the code more readable/self-explainatory.
| try: | ||
| label = data_sngl_file["LABEL"].iloc[0] | ||
| second_magnet = label.split("-")[1] | ||
| relevant = second_magnet.split(".")[-1] | ||
| ip_number = relevant[1:] | ||
| ip_name = f"IP{ip_number}" # --- it extracts the IP from the magnet label, check for typos | ||
| except KeyError as e: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep the try-part as short as possible (usually only one line), to make sure the Key error originates where you expect it to come from.
| cols_x = ["BETSTARX", "ERRBETSTARX", "BETWAISTX", "ERRBETWAISTX", "WAISTX", "ERRWAISTX"] | ||
| cols_y = ["BETSTARY", "ERRBETSTARY", "BETWAISTY", "ERRBETWAISTY", "WAISTY", "ERRWAISTY"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll mark it here, but this is a general comment for the whole function: Use the constants for the columns. Check the other kmod-related files for how it is done there.
| all_av_x, all_av_y = [], [] | ||
| for key, value in averaged_meas_paths.items(): | ||
| LOG.debug(f"Reading averaged results: {key}") | ||
| df_av_x, df_av_y = output_table_single_beam(value[0], av_res_flag=True) | ||
| all_av_x.append(df_av_x) | ||
| all_av_y.append(df_av_y) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rename key and value to what the variables actually mean. (e.g. I have no idea what value[0] is supposed to be.
| # return [round(bstar, 3) for bstar in df_model.loc[ip, [f"{BETA}X", f"{BETA}Y"]]] | ||
| return df_model.loc[ip, [f"{BETA}X", f"{BETA}Y"]].tolist() | ||
|
|
||
| def import_kmod_summary_table( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(removed - updated below)
| cols_y = ["BETSTARY", "ERRBETSTARY", "BETWAISTY", "ERRBETWAISTY", "WAISTY", "ERRWAISTY"] | ||
| beams = [f"{BEAM_DIR}{1}", f"{BEAM_DIR}{2}"] | ||
|
|
||
| def output_table_single_beam( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it makes sense to have this as a nested function.
Co-authored-by: Felix Soubelet <[email protected]>
Adding a script to generate .tfs and .txt tables with the summary of the KMOD measurement imported with kmod_importer. It will generate one .tfs and one .txt table for each beam.
The .txt table has been made to be easily copy/pasted in the logbook keeping a readable format.