Writing to a Skyline data file using an external tool

support
Writing to a Skyline data file using an external tool thr26  2022-08-31
 

Hey, Skyline team,

As the title suggests, I've been developing an external tool (in C#) and have run into a roadblock with implementing some of its functionality. I'm currently trying to write data generated by the tool to the Skyline file itself, data that can be displayed in a column of a custom report in the document grid. However, I can't quite figure out what I need to access in order to assign the data to its intended column/location in the document grid.

I've made the connection from my tool to Skyline with the SkylineToolClient object, and I can read information from it as well as an IReport object using a custom report. The goal of this tool is to read data, generate a flag based on some criteria, and then write the results back into the Skyline file (which are displayed under a column that the custom report specifies). This last part is what I've been having issue with, as the arrays that the IReport objects expose to the user don't seem to have the functionality to update the underlying data file. The values can be easily set by accessing IReport.Cells, however I have indeed realized that the array is not accessing the data itself, only a copy that's presented to the user.

Am I able to have a tool write data to a Skyline file in this way, with it eventually being displayed in the document grid? And if so, what do I need to access to do it?

Thanks for your help, and if I need to provide any more clarification then please let me know.
– Tommy

 
 
Nick Shulman responded:  2022-08-31
The tool service API is not powerful enough to allow you to modify the Skyline document.
One thing that you could do is have your tool use the Skyline command line interface to modify the document.
One of the things that you can do with the commandline is "--import-annotations".
A lot of things can be changed with the CSV file that you provide to "--import-annotations".
If you want to see all of the things that could be modified in this way, you can use the menu item in Skyline:
"File > Export > Annotations".
Anything which you can choose to export in the "Export Annotations and Properties" dialog, you can also import using either the "File > Import > Annotations" menu item or the "--import-annotations" commandline parameter.

If you look at the CSV file that you get when you use the Export Annotations menu item, you can see the format that Skyline would be expecting. The "ElementLocator" column in the exported CSV contains values which are the same as the "PeptideLocator", "PrecursorLocator" etc. columns that you can add to a report.

A different set of values that you can change in the document are those that you can import with "File > Import > Peak Boundaries"

What sort of values were you hoping to change in the Skyline document?
-- Nick
 
thr26 responded:  2022-08-31

Hey Nick,

Thanks for getting back to me with such an informative response. I knew that annotations existed and intended on using a custom number annotation for this, however as you can probably guess I wasn't able to get the tool service API to handle it. For clarity's sake, I essentially wished to append a new column to the document and populate its fields using the tool.

I'm not very familiar with the Skyline command-line, however this process sounds to me like it'll suit my needs. I went and briefly messed around with an annotation column just now and it seems fitting. The file generated by "File > Export > Annotations" is a bit daunting with the sheer size amount of available properties (especially since I exported everything available) however with time I should be able to wrap my head around it. It sounds like writing my values to a properly formatted CSV file and then using the command-line to import the annotation column should do what I want.

How would you suggest calling the command-line from a tool in C#?

Many thanks,
– Tommy

 
Nick Shulman responded:  2022-08-31
There are two ways of running Skyline commandline:
1. If you know which folder Skyline is installed in, there is a file in there called "SkylineCmd.exe".
2. If you will not know which folder Skyline is installed in, then you should download "SkylineRunner.exe" which is available on the Skyline install page:
https://skyline.ms/wiki/home/software/Skyline/page.view?name=SkylineInstall_64_21-2&submit=false
SkylineRunner.exe looks at the Windows Start Menu and finds where Skyline is installed
(there is a separate file "SkylineDailyRunner.exe" which you can download from the Skyline-daily install page which looks in the start menu for Skyline-daily instead of Skyline)

In your C# program, you would use the "Process" class to launch whichever executable you need to:
https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process?view=netframework-4.8

As a C# programmer, you could also use "Assembly.LoadFrom" to load Skyline.exe and then there would be no limit to what you could tell Skyline to do.
-- Nick
 
thr26 responded:  2022-08-31

SkylineRunner is going to be the choice for me then. I anticipate this tool being used on different computers, and while I know how to navigate to Skyline's installation buried in %localappdata% it would definitely be easier to just include a relative reference to SkylineRunner.

My question of how best to call the command-line was inadvertently answered by the SkylineRunner suggestion. I was primarily concerned with referencing the absolute path to an executable, and it seems that SkylineRunner was built with this in mind.

I imagine your note about Assembly.LoadFrom goes outside the scope of my tool (and my knowledge of C#) however I'm still tempted to ask: what sort of things could you get Skyline to do only with this?

– Tommy

 
Nick Shulman responded:  2022-08-31
The implementation of SkylineCmd.exe uses "Assembly.LoadFrom" to load Skyline.exe, and then it invokes the method "pwiz.Skyline.Program.Main".
https://github.com/ProteoWizard/pwiz/blob/master/pwiz_tools/Skyline/SkylineCmd/Program.cs

If that function "Main" is called without any arguments, the main Skyline window will come up. Your program could potentially look at the static field "pwiz.Skyline.Program.MainWindow" and then invoke menu items etc. on the Skyline window.
I don't think anyone has ever tried to extend Skyline's functionality in this way. People have certainly forked the github repository and implemented their new features in their own copy of the Skyline source code.

There is information about how to build Skyline here:
https://skyline.ms/wiki/home/software/Skyline/page.view?name=source

-- Nick
 
thr26 responded:  2022-09-01
I see what you're getting at now. I can imagine loading Skyline in this manner is quite powerful, to the point where pretty much any action could be automated. It sounds like a rather fun project to explore sometime.

I also have succeeding in running the Skyline command-line from my tool. There's plenty more to familiarize myself with here, but this direction should be enough for me to figure things out with a little time. Once again, thanks a ton for your help!

– Tommy
 
thr26 responded:  2022-09-02

I'm back sooner than I wished, but I'm at a loss trying to solve this issue.

A first question while I have your attention: is it possible to enable/create annotations in the "Settings > Document Settings > Annotations" menu programmatically? I'm hoping to start with a document that has none of these settings, and entirely through the tool add the annotation. When I try to do the import without the annotation enabled I get the following message: Annotation 'annotation_Test Column' does not apply to element 'Replicate:/Sample 1', which is the very first replicate in the document. This feels like intended behavior to me but I'd like to be sure.

The real issue of mine is this: I can create my annotation CSV programmatically, however when I try to import it programmatically it doesn't quite work. No error is thrown to the console, but the column in the document grid never updates. No values get added to the column, and it also does not overwrite existing values in the column either. The odd part is that if I go to "File > Import > Annotations" and import the annotation manually, the values do update and behave as expected.

Here's the code I'm using to call the command-line from my tool:

string workdir = Directory.GetCurrentDirectory();

var SkylineCmd = new Process
{
    StartInfo = new ProcessStartInfo
    {
        FileName = "cmd.exe",
        Arguments = $"/k {workdir}\\SkylineCmd.exe "
            + $"--in=\"{_toolClient.GetDocumentPath()}\" "
            + $"--import-annotations={workdir}\\Tools\\SkylineIntegration\\TestAnnotation.csv "
            + $"--tool-zip-overwrite-annotations=true"
    }
};

SkylineCmd.Start();

I've also attached the CSV file I've been using. Any idea why this is happening?

Thanks once again,
– Tommy

 
Nick Shulman responded:  2022-09-02
There is no way to programmatically tell Skyline to add an annotation definition to a document.
You can, however, make it so that Skyline tells the user they have to add the annotation themselves before they launch your external tool.
Inside of your tool zip file, in the .properties file which defines your menu item, you can list the annotations that you need like this:
Annotation1 = Condition
Annotation2 = BioReplicate
(this example comes from "2_MSStatsGC.properties" in the "tool-inf" folder inside of the MSstats external tool zip file. You can download that zip file using the download button on this page:
https://skyline.ms/skyts/home/software/Skyline/tools/details.view?name=MSstats
)

For your commandline, you need to add "--save" at the end of all of the other commandline arguments.
Skyline commandline does not actually save the document unless you explicitly tell it to.
-- Nick
 
thr26 responded:  2022-09-02
I'm glad there exists a feature to prompt users in this way. I see how the developers of MSstats implemented this, and it's a satisfactory alternative for me.

I had a feeling it was going to be something small like that. The misunderstanding most definitely stemmed from me having both the command-line and the UI open at once, thinking one would update the other.

Broken record over here, but I appreciate the help greatly. Thank you.
– Tommy