Skip to content
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

ENH: add getPVAliases and grep_more_ioc scripts #180

Merged
merged 23 commits into from
May 23, 2024

Conversation

aberges-SLAC
Copy link
Contributor

@aberges-SLAC aberges-SLAC commented Apr 22, 2024

Description

Added a script for reconstructing PV aliases from their child IOC's, st.cmd files, and .archive files for use in ArchiverAppliance scripts. Does a pythonic grep_ioc for the regex pattern supplied, then searches the child IOC for the parent's release pointer. After confirmation, reconstructs all the record ←→ aliases using .../db/*.archive and st.cmd from the child IOC.

Also added a script called grep_more_ioc which is an a personal utility inspired by grep_ioc . Most of the legwork of this script is reused in getPVAlias so I decided to bundle it for posterity.

Motivation and Context

Motors, namely SmarActs and Elliptecs, tend to move around to different areas often and/or have dynamic configurations for channels based on the area's application. This results in PV aliases becoming stale references to channels that no longer house that stage. To rectify this, you'll need to get the currently built association of EPICS records ←→ aliases for the PVs.

Additionally, I added some QOL in grep_more_ioc that helps day-to-day controls work in CLI without having to open the iocmanager gui.

How Has This Been Tested?

I've run this script & wrapper in an ipython session and using the supplied bash wrapper. Please see the screenshots below!

Where Has This Been Documented?

All documentation is supplied inline on the scripts with accompanying usage/help doctext.

Screenshots (if appropriate):

getPVAliases

Initial confirmation of ioc caught by a grep_ioc like search:
image

All axes/motors generated by the child IOC's st.cmd file:
image

Preview of what will be saved to the .txt file dumps:
image

Assumes current directory as the base for new folder generation & dump, but accepts different directories:
image

Makes the folder if it does not exist, then iterates to the next IOC:
image

Individual axes can be skipped, with lazy skipping through the rest of the axes:
image

--> Otherwise if you don't accept all axes dumped, (or lazy accept/skip the rest), you will be asked to confirm each dump:
image

Example of output:
image


grep_more_ioc

This script uses pandas to print DataFrames, which is quite slower than prettytable but doesn't suffer the wrapping/width issues that the latter does. (see below)
image

There are 2 major functions: print and search. In my examples below I'll use the alias gmi for grep_more_ioc

print

Options:

  • skip_comments
    image
    Functions like cat, except you skip commented code. Useful for quickly grabbing IOC information when building happi entries.

  • release
    image
    Searches the child IOCs for the release pointer, then adds an abbreviated path to the parent's current release.

  • print_dirs
    image
    Dumps directories to terminal for quicker copy/pasting/pushd

search

Options:

  • quiet
    image
    image
    Suppress warnings for paths that don't exist when doing batch searches (as disabled IOCs are often previously deleted...)

  • only
    image
    Only print the search results, don't print the DataFrame.

@aberges-SLAC aberges-SLAC self-assigned this Apr 22, 2024
Copy link
Contributor

@tangkong tangkong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work, seems like this should be very helpful! I've left a couple nitpicky notes, I'll take a bit to look at this from a higher level after this.

  • I like to avoid regex when possible. It's powerful but often difficult to maintain and parse (by humans). There's a few places here where I don't think you need it.
  • Thanks for the comments / docstrings! Love to see it.

scripts/getPVAliases.py Outdated Show resolved Hide resolved
scripts/getPVAliases.py Outdated Show resolved Hide resolved
scripts/getPVAliases.sh Outdated Show resolved Hide resolved
scripts/getPVAliases.sh Outdated Show resolved Hide resolved
Copy link
Member

@ZLLentz ZLLentz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Script is good, put in my suggestions and nitpicks

scripts/getPVAliases.sh Outdated Show resolved Hide resolved
scripts/getPVAliases.py Show resolved Hide resolved
scripts/getPVAliases.sh Outdated Show resolved Hide resolved
scripts/getPVAliases.py Outdated Show resolved Hide resolved
scripts/getPVAliases.py Outdated Show resolved Hide resolved
scripts/getPVAliases.sh Outdated Show resolved Hide resolved
scripts/getPVAliases.py Outdated Show resolved Hide resolved
@aberges-SLAC aberges-SLAC changed the title getPVAlias getPVAliases + grep_more_ioc May 14, 2024
@aberges-SLAC aberges-SLAC changed the title getPVAliases + grep_more_ioc ENH: add getPVAliases and grep_more_ioc scripts May 14, 2024
Copy link
Contributor

@tangkong tangkong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A quick once through, not paying too much attention to the logic (which I had assumed did not change much from my last review). But after reading through I think I want to look at the details more closely

scripts/getPVAliases.py Outdated Show resolved Hide resolved
scripts/getPVAliases.py Outdated Show resolved Hide resolved
scripts/getPVAliases.py Outdated Show resolved Hide resolved
scripts/getPVAliases.py Show resolved Hide resolved
scripts/getPVAliases.py Outdated Show resolved Hide resolved
scripts/grep_more_ioc.py Outdated Show resolved Hide resolved
scripts/grep_more_ioc.py Outdated Show resolved Hide resolved
scripts/grep_more_ioc.py Outdated Show resolved Hide resolved
# %%% print
# --------------------------------------------------------------------------- #
# print the dataframe
if hasattr(args, 'print'):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is probably not the recommended way to determine which subparser is being invoked, but I can't immediately come up with a better way 😞

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the sparse nature of argparse (:badumtiss:) including only the invoked parser & subparser made it weird for testing, and I got distracted by other things and didn't leave a note to clean up.

I should probably do something with subparser.set_default to give me some namespace clues. Something like subparser.set_default(command='print') etc.

Copy link
Contributor Author

@aberges-SLAC aberges-SLAC May 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out my original approach is one of the few stable ways to check for other possible args. When argparse parses the args, if any subparser is unused, none of its attributes get populated in the resultant Namespace object.
image
image

I guess the other way of doing this would be generating a full Namespace object with all of the defaults set and to check the bool of any sub-commands because I already structured them as simple toggles at the top level.
Something like:

class Args:
    self.patt = None
    self.hutch = None
    self.ignore_disabled = False
    ...

But then I'm hard coding all the defaults anyway that argparse was originally handling. 🤷

scripts/getPVAliases.sh Outdated Show resolved Hide resolved
@ZLLentz
Copy link
Member

ZLLentz commented May 15, 2024

I'm starting to feel like this has been stuck in review cycle for longer than it needs to be relative to how complete the code is, so I'm going to try to focus my reviews on bigger things related to deploying/sharing/using the scripts. I can't wait to see this in engineering tools proper.

@aberges-SLAC
Copy link
Contributor Author

I just caught a bug that's worth fixing before merging as well. Happens when you print -c or print -r on the very rare case where a child_ioc.cfg doesn't actually exist, but the ioc is absolutely valid and in HUTCH/iocmanager.cfg cough PLCs cough.

I'm really just commenting this here to remind myself to use try/except with search_file for handling these edge cases.
image

@aberges-SLAC
Copy link
Contributor Author

Okay, I fixed the bug when searching IOCs that had ',\n history: [...' causing the IOC to get skipped during the search. Added a sub-function for printing these history attributes within grep_more_ioc but I'll add that to the README.md in post, since the pre-commit hates the README.md syntax.

@ZLLentz
Copy link
Member

ZLLentz commented May 20, 2024

the pre-commit hates the README.md syntax

What's the story here? Maybe we need to make some of the pre-commit entries ignore the readme?

@aberges-SLAC
Copy link
Contributor Author

the pre-commit hates the README.md syntax

What's the story here? Maybe we need to make some of the pre-commit entries ignore the readme?

It complained loudly at me for markdown syntax that I never edited, and then seemingly wanted to remove lines like <tr/> just to add them back. It was somewhere like 6-7 commits ago when I was struggling to get the pre-commit to accept me (turns out adding it to my local repo helps [:).

Just let it its thing and committed the pre-commit changes a few tries ago. Now that it is happy I'm hesitant to make any further modifications. Besides, its much cleaner on the web interface anyhow.

@tangkong
Copy link
Contributor

The README.md probably hadn't been pre-commit-checked, since our checks only run on modified files.

<tr>
<td>grep_more_ioc</td>
<td>
usage: grep_more_ioc [-h] [-d] patt hutch {print,search} <br/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script is actually grep_more_ioc.sh, I think we should document as such here or rename the scripts to not have .sh suffixes.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd vote to not have .sh as most scripts in engineering tools do not have extensions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To hop on to the readme suggestions, could you add an example call for those of us who don't know what pattern/hutch to search for? I think examples are helpful for people not so familiar with EPICS and our systems

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if this script renaming/examples stuff get in then this PR has my approval (I don't want to hold it up any longer, but I'd like the names to be finalized + I'd like people to be ready to use it when it gets merged)

README.md Outdated
Comment on lines 253 to 254
patt Regex str to search through iocmanager.cfg<br/>
hutch hutch to search<br/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two are documented well here but not in the --help text for either script. I don't think patt is self-describing enough.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$ grep_more_ioc.sh --help
usage: grep_more_ioc [-h] [-d] patt hutch {print,search} ...

Transforms grep_ioc output to json object and prints in pandas.DataFrame

positional arguments:
  patt
  hutch
  {print,search}        Follow-up commands after grep_ioc executes
    print               Just a simple print of the dataframe to the terminal.
    search              For using regex-like searches in the child IOC.cfg captured by grep_ioc. Useful for quickly gathering instance information, IP addr, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can improve this in the argparse documentation so it is more transparent.

The annoying thing about how argparse handles subparsers is that each subparser has its own help text, so something like:
grep_more_ioc.sh . all print --help triggers the help text for print
grep_more_ioc.sh . all search --help triggers the help text for search

Personally, I hate it, but I haven't found a good enough work around yet

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One simple thing you could do is add some text in the top-level parser that hints the user to try those sub-parser help messages.

print(build_table(alias_dicts, ['record', 'alias'], align='l'))
# optional skip for all resulting PV aliases
save_all = (simple_prompt(
'Do you want to save all resulting PV aliases? '
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this message telling me as a user? What is being saved and to where?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should update this docstring to "Do you want to add all resulting PV <--> alias associations to the final output?"

The script now saves a single file with all the results appended together (less annoying to parse when you're playing with the result later). Since you're iterating through a base PV and its resulting PVs (each with aliases), instead of pestering the user to approve every single instance (e.g. each axis in an MCS2 ioc), the user can approve if the first association looks good.

Copy link
Member

@ZLLentz ZLLentz May 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if the script saves a file we should mention this in the help text.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More informative?
image

Copy link
Member

@ZLLentz ZLLentz May 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's definitely better but I think my overall confusion was a lack of understanding that this script was supposed to save anything at all.

script name "get pv aliases", help text "gathers all record <-> alias associations" = confusion about a save prompt

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With some massaging on argparse.RawTextHelpFormatter:
image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! Very helpful output!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like this script doesn't do anything unless I also select print or search, is this the expected behavior?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they are positional arguments. I contemplated making grep_more_ioc.sh <patt> <hutch> default to print but it gets hairy with the subparsers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also improved:
image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one looks good too!

@ZLLentz
Copy link
Member

ZLLentz commented May 21, 2024

I ran the scripts myself and asked the questions that I had as a user, maybe they inform documentation/examples/etc.

@aberges-SLAC
Copy link
Contributor Author

Okay, all help doc-text improved, committed, and pushed!

tangkong
tangkong previously approved these changes May 22, 2024
Copy link
Contributor

@tangkong tangkong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. I think future improvements probably deserve their own separate PRs. This is some good work! 👍

Copy link
Member

@ZLLentz ZLLentz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The final tiny thing before merge is the script names, the majority of the executables in engineering_tools don't have the .sh extension, so I suggest renaming these to remove it.

It's worth noting that you've already documented this without the .sh extension in the readme, so renaming things makes everything consistent.

Otherwise, if there's a good reason to keep the .sh, it should be documented as such in the readme.

Added getPVAliases to README and fixed formatting
@aberges-SLAC
Copy link
Contributor Author

The final tiny thing before merge is the script names, the majority of the executables in engineering_tools don't have the .sh extension, so I suggest renaming these to remove it.

It's worth noting that you've already documented this without the .sh extension in the readme, so renaming things makes everything consistent.

Otherwise, if there's a good reason to keep the .sh, it should be documented as such in the readme.

Done and done! see new commits

@aberges-SLAC aberges-SLAC requested a review from ZLLentz May 22, 2024 20:03
Copy link
Member

@ZLLentz ZLLentz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's get this in!

@ZLLentz
Copy link
Member

ZLLentz commented May 23, 2024

I'm going to merge this now. Post-merge if there are other concerns we can handle them in smaller, reviewable follow-up PRs. We can either tag/deploy this immediately or we can wait, let me know what you all prefer.

@ZLLentz ZLLentz merged commit da49912 into pcdshub:master May 23, 2024
2 checks passed
@aberges-SLAC
Copy link
Contributor Author

I'm going to merge this now. Post-merge if there are other concerns we can handle them in smaller, reviewable follow-up PRs. We can either tag/deploy this immediately or we can wait, let me know what you all prefer.

I'm excited to get this out for folks to use & stress test. I'm sure there's more bugs hiding somewhere that's outside of my normal use cases. So I'm in favor of deployment sooner rather than later — the script is pretty stable for now.

Are there any confluences pages I should update as well? Or do we leave the documentation in the README.md?

@ZLLentz
Copy link
Member

ZLLentz commented May 23, 2024

I'll release another version right away then- tags are cheap. Do you want to announce the release of R3.8.0 (which, compared to last version, only has this PR) or would you prefer I do it?

I don't think there's any confluence page in particular that needs to be updated, unless you think a bigger page about usage etc. would be useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants