private void TestTargetedMsmsCommon(string templateFilePath, string methodFilePath, bool doTOFMs) { var method = GetMethod(methodFilePath); Assert.AreEqual(1, method.PeriodCount); var period = (Period)method.GetPeriod(0); // Read in the template method for comparison MassSpecMethod templateMethod = GetMethod(templateFilePath); var prodIonIndex = ((Period)templateMethod.GetPeriod(0)).ExperimCount == 1 ? 0 : 1; var templateProdIonExpt = (Experiment)((Period)(templateMethod.GetPeriod(0))).GetExperiment(prodIonIndex); var templateTofMsExpt = ((Period)templateMethod.GetPeriod(0)).ExperimCount == 2 ? (Experiment)((Period)(templateMethod.GetPeriod(0))).GetExperiment(0) : null; if (doTOFMs) { // We should have 1 "TOF MS" experiments and 20 "Product Ion" experiments Assert.AreEqual(21, period.ExperimCount); // first experiment should be a TOF experiment var experiment = (Experiment)period.GetExperiment(0); Assert.AreEqual(BuildAnalystFullScanMethod.TOF_MS_SCAN, experiment.ScanType); if (templateTofMsExpt != null) { CompareExperiments(templateTofMsExpt, experiment, IsQstarTemplate(templateFilePath)); } experiment = (Experiment)period.GetExperiment(1); Assert.AreEqual(BuildAnalystFullScanMethod.PROD_ION_SCAN, experiment.ScanType); CompareExperiments(templateProdIonExpt, experiment, IsQstarTemplate(templateFilePath)); } else { // We should have 20 "Product Ion" experiments Assert.AreEqual(20, period.ExperimCount); var experiment = (Experiment)period.GetExperiment(0); Assert.AreEqual(BuildAnalystFullScanMethod.PROD_ION_SCAN, experiment.ScanType); CompareExperiments(templateProdIonExpt, experiment, IsQstarTemplate(templateFilePath)); } }
public void TestMRMMethod() { string projectDirectory = GetProjectDirectory(); var args = new[] { Path.Combine(projectDirectory, METHOD_FILE), Path.Combine(projectDirectory, LIST_UNSCHED) }; var builder = new BuildQtrapMethod(); builder.ParseCommandArgs(args); builder.build(); string methodFilePath = Path.GetFullPath(Path.Combine(projectDirectory, METHOD_UNSCHED)); // read the updated method and make sure that the // transition list has been included MassSpecMethod method = GetMethod(methodFilePath); var period = (Period)method.GetPeriod(0); var msExperiment = (Experiment)period.GetExperiment(0); Assert.AreEqual(60, msExperiment.MassRangesCount); // Check the first one // 744.839753,1087.49894,20,APR.AGLCQTFVYGGCR.y9.light,85.4,38.2 var massRange = (MassRange)msExperiment.GetMassRange(0); Assert.AreEqual(20, massRange.DwellTime); Assert.AreEqual(744.839753, massRange.QstartMass, 0.00005); Assert.AreEqual(0, massRange.QstopMass); Assert.AreEqual(1087.49894, massRange.QstepMass, 0.00005); var msMassRange3 = (IMassRange3)massRange; Assert.AreEqual("APR.AGLCQTFVYGGCR.y9.light", msMassRange3.CompoundID); // Check the last one // 572.791863,724.375566,20,CRP.GYSIFSYATK.y6.heavy,72.6,28.2 massRange = (MassRange)msExperiment.GetMassRange(59); Assert.AreEqual(20, massRange.DwellTime); Assert.AreEqual(572.791863, massRange.QstartMass, 0.00005); Assert.AreEqual(0, massRange.QstopMass); Assert.AreEqual(724.375566, massRange.QstepMass, 0.00005); msMassRange3 = (IMassRange3)massRange; Assert.AreEqual("CRP.GYSIFSYATK.y6.heavy", msMassRange3.CompoundID); DeleteOutput(methodFilePath); }
internal static IAcqMethod GetAcqMethod(string methodFilePath, out MassSpecMethod templateMsMethod) { ApplicationClass analyst = new ApplicationClass(); // Make sure that Analyst is fully started IAcqMethodDirConfig acqMethodDir = (IAcqMethodDirConfig)analyst.Acquire(); if (acqMethodDir == null) { throw new IOException("Failed to initialize. Analyst may need to be started."); } object acqMethodObj; acqMethodDir.LoadNonUIMethod(methodFilePath, out acqMethodObj); IAcqMethod templateAcqMethod = (IAcqMethod)acqMethodObj; templateMsMethod = ExtractMsMethod(templateAcqMethod); return(templateAcqMethod); }
private void ValidateMethod(MassSpecMethod method) { // Do some validation that happens regardless of instrument if (method == null) { throw new IOException(string.Format("Failed to open template method {0}. " + "The given template may be invalid for the available version of Analyst.", TemplateMethod)); } if (method.PeriodCount == 0) { throw new IOException(string.Format("Invalid template method {0}. Expecting at least one period.", TemplateMethod)); } // Get the last period in the given template method. // We will add transitions to the last period only. var msPeriod = (Period)method.GetPeriod(method.PeriodCount - 1); var msExperiment = (Experiment)msPeriod.GetExperiment(0); var experimentType = msExperiment.ScanType; if (experimentType != 4) { throw new IOException(string.Format("Invalid template method {0}. Experiment type must be MRM.", TemplateMethod)); } var msExperiment7 = (IExperiment7)msExperiment; if (RTWindowInSeconds.HasValue) { msExperiment7.LCPeakWidth = RTWindowInSeconds.Value; msExperiment7.KnownRetentionTimes = 1; } else { msExperiment7.KnownRetentionTimes = 0; } }
private static bool IsDataDependentMethod(MassSpecMethod method) { return(((IMassSpecMethod2)method).DataDependent == 1); }
private void WriteToTargetedMSMSTemplate(MassSpecMethod method, MethodTransitions transitions) { var period = (Period)method.GetPeriod(0); Experiment tofExperiment = null; Experiment prodIonExperiment; switch (period.ExperimCount) { case 2: tofExperiment = (Experiment)period.GetExperiment(0); prodIonExperiment = (Experiment)period.GetExperiment(1); // delete the product ion experiment. We will be adding one for each precursor ion in the transition list. period.DeleteExperiment(1); break; case 1: prodIonExperiment = (Experiment)period.GetExperiment(0); // delete the product ion experiment. We will be adding one for each precursor ion in the transition list. period.DeleteExperiment(0); break; default: throw new IOException(string.Format("Expected 1 or 2 experiments in the template. Found {0} experiments.", period.ExperimCount)); } int j; if (Ms1Scan) { // If the template does not already have a TOF MS scan add one now. if (tofExperiment == null) { var experiment = (Experiment)period.CreateExperiment(out j); experiment.InitExperiment(); experiment.ScanType = TOF_MS_SCAN; } } if (prodIonExperiment == null) { throw new IOException("Product Ion scan was not found in the method."); } // Get the TOF mass range from the template var tofPropertiesTemplate = (ITOFProperties)prodIonExperiment; short s; //Get initial source parameters from the template var sourceParamsTblInput = (ParamDataColl)prodIonExperiment.SourceParamsTbl; ParameterData param = (ParameterData)sourceParamsTblInput.FindParameter("GS1", out s); float sourceGas1 = param == null ? 0 : param.startVal; param = (ParameterData)sourceParamsTblInput.FindParameter("GS2", out s); float sourceGas2 = param == null ? 0 : param.startVal; param = (ParameterData)sourceParamsTblInput.FindParameter("CUR", out s); float curtainGas = param == null ? 0 : param.startVal; param = (ParameterData)sourceParamsTblInput.FindParameter("TEM", out s); float temperature = param == null ? 0 : param.startVal; param = (ParameterData)sourceParamsTblInput.FindParameter("IHT", out s); float nanoTemperature = param == null ? 0 : param.startVal; string ionSprayVoltageParamName = "ISVF"; // ISVF on 5600, IS on QSTAR float ionSprayVoltage; var paramData = ((ParameterData)sourceParamsTblInput.FindParameter(ionSprayVoltageParamName, out s)); if (s != -1) { ionSprayVoltage = paramData.startVal; } else { ionSprayVoltageParamName = "IS"; ionSprayVoltage = ((ParameterData)sourceParamsTblInput.FindParameter(ionSprayVoltageParamName, out s)).startVal; } // We will use parameters from the first mass range in the template product ion experiment. var massRangeTemplate = (IMassRange)prodIonExperiment.GetMassRange(0); var paramTblTemplate = (ParamDataColl)massRangeTemplate.MassDepParamTbl; double minPrecursorMass = double.MaxValue; double maxPrecursorMass = 0; var precursorsToExperimentIndex = new Dictionary <double, int>(); foreach (var transition in transitions.Transitions) { if (precursorsToExperimentIndex.ContainsKey(transition.PrecursorMz)) { transition.ExperimentIndex = IsPrecursorTypeTransition(transition) ? 0 : precursorsToExperimentIndex[transition.PrecursorMz]; continue; } var experiment = (Experiment)period.CreateExperiment(out j); precursorsToExperimentIndex.Add(transition.PrecursorMz, j); transition.ExperimentIndex = IsPrecursorTypeTransition(transition) ? 0 : j; experiment.InitExperiment(); // Setting ScanType to 6 for QSTAR causes method export to fail. Setting it to 9 works for both AB 5600 and QSTAR experiment.ScanType = PROD_ION_SCAN; experiment.FixedMass = transition.PrecursorMz; minPrecursorMass = Math.Min(minPrecursorMass, transition.PrecursorMz); maxPrecursorMass = Math.Max(maxPrecursorMass, transition.PrecursorMz); var tofProperties = (ITOFProperties)experiment; tofProperties.AccumTime = tofPropertiesTemplate.AccumTime; tofProperties.TOFMassMin = tofPropertiesTemplate.TOFMassMin; tofProperties.TOFMassMax = tofPropertiesTemplate.TOFMassMax; // The following should trigger the "Suggest" button functionality // of updating the Q2 transmission window. tofProperties.UseQ1TranDefault = 1; //tofProperties.UseTOFExtrDefault = 1; // Works without this one. // High Sensitivity vs. High Resolution var tofProperties2 = experiment as ITOFProperties2; var templateTofProperties2 = prodIonExperiment as ITOFProperties2; if (tofProperties2 != null && templateTofProperties2 != null) { tofProperties2.HighSensitivity = templateTofProperties2.HighSensitivity; } var sourceParamsTblOutput = (ParamDataColl)experiment.SourceParamsTbl; if (sourceParamsTblInput.FindParameter("GS1", out s) != null && s != -1) { sourceParamsTblOutput.AddSetParameter("GS1", sourceGas1, sourceGas1, 0, out s); } if (sourceParamsTblInput.FindParameter("GS2", out s) != null && s != -1) { sourceParamsTblOutput.AddSetParameter("GS2", sourceGas2, sourceGas2, 0, out s); } if (sourceParamsTblInput.FindParameter("CUR", out s) != null && s != -1) { sourceParamsTblOutput.AddSetParameter("CUR", curtainGas, curtainGas, 0, out s); } if (sourceParamsTblInput.FindParameter("TEM", out s) != null && s != -1) { sourceParamsTblOutput.AddSetParameter("TEM", temperature, temperature, 0, out s); } if (sourceParamsTblInput.FindParameter("IHT", out s) != null && s != -1) { sourceParamsTblOutput.AddSetParameter("IHT", nanoTemperature, nanoTemperature, 0, out s); } if (sourceParamsTblInput.FindParameter(ionSprayVoltageParamName, out s) != null && s != -1) { sourceParamsTblOutput.AddSetParameter(ionSprayVoltageParamName, ionSprayVoltage, ionSprayVoltage, 0, out s); } // Copy the compound dependent parameters from the template for (int i = 0; i < experiment.MassRangesCount; i++) { var massRange = (IMassRange)experiment.GetMassRange(i); var massDepParams = (ParamDataColl)massRange.MassDepParamTbl; // Declustering potential float dp = ((ParameterData)paramTblTemplate.FindParameter("DP", out s)).startVal; if (s != -1) { if (transition.DP > 0) { dp = Convert.ToSingle(transition.DP); } massDepParams.AddSetParameter("DP", dp, dp, 0, out s); } // Collision engergy float ce = ((ParameterData)paramTblTemplate.FindParameter("CE", out s)).startVal; if (s != -1) { if (transition.CE > 0) { ce = Convert.ToSingle(transition.CE); } massDepParams.AddSetParameter("CE", ce, ce, 0, out s); } // Ion release delay float ird = ((ParameterData)paramTblTemplate.FindParameter("IRD", out s)).startVal; if (s != -1) { massDepParams.AddSetParameter("IRD", ird, ird, 0, out s); } // Ion release width float irw = ((ParameterData)paramTblTemplate.FindParameter("IRW", out s)).startVal; if (s != -1) { massDepParams.AddSetParameter("IRW", irw, irw, 0, out s); } // Collision energy spread; Only on the Analyst TF 1.5.1 and TF1.5.2 paramData = ((ParameterData)paramTblTemplate.FindParameter("CES", out s)); if (s != -1) { massDepParams.AddSetParameter("CES", paramData.startVal, paramData.startVal, 0, out s); } // Focusing potential; Only on Analyst QS 2.0 paramData = ((ParameterData)paramTblTemplate.FindParameter("FP", out s)); if (s != -1) { massDepParams.AddSetParameter("FP", paramData.startVal, paramData.startVal, 0, out s); } // Declustering potential 2; Only on Analyst QS 2.0 paramData = ((ParameterData)paramTblTemplate.FindParameter("DP2", out s)); if (s != -1) { massDepParams.AddSetParameter("DP2", paramData.startVal, paramData.startVal, 0, out s); } // Collision gas; Only on Analyst QS 2.0 paramData = ((ParameterData)paramTblTemplate.FindParameter("CAD", out s)); if (s != -1) { massDepParams.AddSetParameter("CAD", paramData.startVal, paramData.startVal, 0, out s); } } } // Expand the mass range for the TOF MS scan if the precursor mass of any of the MS/MS experiments // was out of the range if (Ms1Scan) { var ms1TofProperties = (ITOFProperties)(period.GetExperiment(0)); ms1TofProperties.TOFMassMin = Math.Min(ms1TofProperties.TOFMassMin, minPrecursorMass); ms1TofProperties.TOFMassMax = Math.Max(ms1TofProperties.TOFMassMax, maxPrecursorMass); } }
private void WriteToIDATemplate(MassSpecMethod method, MethodTransitions transitions) { object idaServer; ((IMassSpecMethod2)method).GetDataDependSvr(out idaServer); ClearIncludeList(idaServer); double minTOFMass = 0; double maxTOFMass = 0; ((IDDEMethodObj)idaServer).getUsersSurvTOFMasses(ref minTOFMass, ref maxTOFMass); var addedEntries = new List <string>(); var assignedCandidateMassToRT = new Dictionary <double, double>(); var entryKeyToAssignedCandidateMass = new Dictionary <string, double>(); foreach (var transition in transitions.Transitions) { double retentionTime = 0; // If the ScheduledMethod flag was set assume that the Dwell time column in the // transition list file has retention time. if (ScheduledMethod) { retentionTime = transition.Dwell; } string entryKey = transition.PrecursorMz + retentionTime.ToString(CultureInfo.InvariantCulture); if (addedEntries.Contains(entryKey) || transition.PrecursorMz <= minTOFMass || transition.PrecursorMz >= maxTOFMass) { continue; } var precursorMz = Math.Round(transition.PrecursorMz, 3); while (assignedCandidateMassToRT.ContainsKey(precursorMz)) { // Analyst does not allow duplicate masses in inclusion list precursorMz += 0.001; } ((IDDEMethodObj)idaServer).AddIonEntry(1, precursorMz, retentionTime); addedEntries.Add(entryKey); assignedCandidateMassToRT.Add(precursorMz, retentionTime); entryKeyToAssignedCandidateMass.Add(entryKey, precursorMz); } if (ScheduledMethod) // calculate experiment index which is used for exporting a quantitaion method { ((IDDEMethodObj)idaServer).putExceedCountSwitch(2000000); ((IDDEMethodObj)idaServer).putIntensityThreshold(0); int windowInSec = RTWindowInSeconds.HasValue ? RTWindowInSeconds.Value : 60; ((IDDEMethodObj3)idaServer).putIncludeForSecs(windowInSec); int maxConcurrentCount = MaxConcurrentCount(assignedCandidateMassToRT, windowInSec); ((IDDEMethodObj)idaServer).putSpectraSwitch(maxConcurrentCount); var period = (Period)method.GetPeriod(0); while (period.ExperimCount > 2) { period.DeleteExperiment(period.ExperimCount - 1); } var templateExperiment = (Experiment)period.GetExperiment(1); for (int newExperimentIdx = 1; newExperimentIdx < maxConcurrentCount; newExperimentIdx++) { int pIdx; var experiment = (IClone)period.CreateExperiment(out pIdx); experiment.CopyDataFrom(templateExperiment); } // sort by mass then by RT var massRtList = assignedCandidateMassToRT.OrderBy(c => c.Value).ThenBy(c => c.Key).ToList(); foreach (var transition in transitions.Transitions) { double assignedCandidateMass; var entryKey = transition.PrecursorMz + transition.Dwell.ToString(CultureInfo.InvariantCulture); if (!entryKeyToAssignedCandidateMass.TryGetValue(entryKey, out assignedCandidateMass)) { continue; } var scheduledIndex = massRtList.FindIndex(m => Math.Abs(m.Key - assignedCandidateMass) < 0.001); transition.ExperimentIndex = IsPrecursorTypeTransition(transition) ? 0 : (scheduledIndex % maxConcurrentCount) + 1; } } }
private void ValidateMethod(MassSpecMethod method) { if (method == null) { throw new IOException(string.Format("Failed to open template method {0}. " + "The given template may be invalid for the available version of Analyst.", TemplateMethod)); } if (method.PeriodCount != 1) { throw new IOException(string.Format("Invalid template method {0}. Expecting only one period.", TemplateMethod)); } var period = (Period)method.GetPeriod(0); var experimentCount = period.ExperimCount; if (InclusionList || ScheduledMethod) { if (!IsDataDependentMethod(method)) { throw new IOException(string.Format("Invalid template method for an IDA or Scheduled experiment {0}. " + "Template does not support inclusion lists.", TemplateMethod)); } // A valid IDA method will have at least one TOF MS scan and one Product Ion scan // On the 5600 (Analyst TF1.5)we can have 1 or 2 TOF MS scans followed by 1 Product Ion scan // On the QSTAR (Analyst 2.0) we should have 1 TOF MS scan followed by 1 or more Product Ion scans if (experimentCount < 2) { throw new IOException(string.Format("Invalid template method for an IDA or Scheduled experiment {0}. " + "Template must have one or two TOF MS experiments and at least one Product Ion experiment.", TemplateMethod)); } // get the first experiment, it should be a TOF MS experiment var msExperiment = (Experiment)period.GetExperiment(0); if (!IsTofMsScan(msExperiment)) { throw new IOException(string.Format("Invalid template method for an IDA or Scheduled experiment {0}. " + "First experiment type must be TOF MS.", TemplateMethod)); } // get the last experiment, it should be a Product ion experiment msExperiment = ((Experiment)period.GetExperiment(experimentCount - 1)); if (!IsProductIonScan(msExperiment)) { throw new IOException(string.Format("Invalid template method for an IDA or Scheduled experiment {0}. " + "Last experiment type must be Product Ion Scan.", TemplateMethod)); } } else { if (IsDataDependentMethod(method)) { throw new IOException(string.Format("Invalid template method for a targeted MS/MS experiment {0}. " + "The given template is for a data dependent experiment.", TemplateMethod)); } if (experimentCount != 1 && experimentCount != 2) { throw new IOException(string.Format("Invalid template method for a targeted MS/MS experiment {0}. " + "Template must have 1 or 2 experiments.", TemplateMethod)); } // If the template has 1 experiment it should be a Product Ion experiment if (experimentCount == 1) { var msExperiment = (Experiment)period.GetExperiment(0); if (!IsProductIonScan(msExperiment)) { throw new IOException(string.Format("Invalid template method for a targeted MS/MS experiment {0}. " + "Template does not have a Product Ion Scan.", TemplateMethod)); } } // If the template has 2 experiments require the first one to be a TOF MS and the second one to be a Product Ion if (experimentCount == 2) { var msExperiment = (Experiment)period.GetExperiment(0); if (!IsTofMsScan(msExperiment)) { throw new IOException(string.Format("Invalid template method for a targeted MS/MS experiment {0}. " + "Template has 2 experiments. First experiment type must be TOF MS.", TemplateMethod)); } msExperiment = (Experiment)period.GetExperiment(1); if (!IsProductIonScan(msExperiment)) { throw new IOException(string.Format("Invalid template method for a targeted MS/MS experiment {0}. " + "Template has 2 experiments. Second experiment type must be Product Ion Scan.", TemplateMethod)); } } } }
private void WriteToIDATemplate(MassSpecMethod method, MethodTransitions transitions) { object idaServer; ((IMassSpecMethod2)method).GetDataDependSvr(out idaServer); ClearIncludeList(idaServer); double minTOFMass = 0; double maxTOFMass = 0; ((IDDEMethodObj)idaServer).getUsersSurvTOFMasses(ref minTOFMass, ref maxTOFMass); var addedEntries = new List<string>(); var assignedCandidateMassToRT = new Dictionary<double, double>(); var entryKeyToAssignedCandidateMass = new Dictionary<string, double>(); foreach (var transition in transitions.Transitions) { double retentionTime = 0; // If the ScheduledMethod flag was set assume that the Dwell time column in the // transition list file has retention time. if (ScheduledMethod) retentionTime = transition.Dwell; string entryKey = transition.PrecursorMz + retentionTime.ToString(CultureInfo.InvariantCulture); if (addedEntries.Contains(entryKey) || transition.PrecursorMz <= minTOFMass || transition.PrecursorMz >= maxTOFMass) continue; var precursorMz = Math.Round(transition.PrecursorMz, 3); while (assignedCandidateMassToRT.ContainsKey(precursorMz)) { // Analyst does not allow duplicate masses in inclusion list precursorMz += 0.001; } ((IDDEMethodObj)idaServer).AddIonEntry(1, precursorMz, retentionTime); addedEntries.Add(entryKey); assignedCandidateMassToRT.Add(precursorMz, retentionTime); entryKeyToAssignedCandidateMass.Add(entryKey, precursorMz); } if (ScheduledMethod) // calculate experiment index which is used for exporting a quantitaion method { ((IDDEMethodObj)idaServer).putExceedCountSwitch(2000000); ((IDDEMethodObj)idaServer).putIntensityThreshold(0); int windowInSec = RTWindowInSeconds.HasValue ? RTWindowInSeconds.Value : 60; ((IDDEMethodObj3)idaServer).putIncludeForSecs(windowInSec); int maxConcurrentCount = MaxConcurrentCount(assignedCandidateMassToRT, windowInSec); ((IDDEMethodObj)idaServer).putSpectraSwitch(maxConcurrentCount); var period = (Period)method.GetPeriod(0); while (period.ExperimCount > 2) { period.DeleteExperiment(period.ExperimCount -1); } var templateExperiment = (Experiment) period.GetExperiment(1); for (int newExperimentIdx = 1; newExperimentIdx < maxConcurrentCount; newExperimentIdx++) { int pIdx; var experiment = (IClone)period.CreateExperiment(out pIdx); experiment.CopyDataFrom(templateExperiment); } // sort by mass then by RT var massRtList = assignedCandidateMassToRT.OrderBy(c => c.Value).ThenBy(c => c.Key).ToList(); foreach (var transition in transitions.Transitions) { double assignedCandidateMass; var entryKey = transition.PrecursorMz + transition.Dwell.ToString(CultureInfo.InvariantCulture); if (!entryKeyToAssignedCandidateMass.TryGetValue(entryKey, out assignedCandidateMass)) continue; var scheduledIndex = massRtList.FindIndex(m => Math.Abs(m.Key - assignedCandidateMass) < 0.001); transition.ExperimentIndex = IsPrecursorTypeTransition(transition) ? 0 : (scheduledIndex%maxConcurrentCount) + 1; } } }
private void WriteToTargetedMSMSTemplate(MassSpecMethod method, MethodTransitions transitions) { var period = (Period)method.GetPeriod(0); Experiment tofExperiment = null; Experiment prodIonExperiment; switch (period.ExperimCount) { case 2: tofExperiment = (Experiment) period.GetExperiment(0); prodIonExperiment = (Experiment) period.GetExperiment(1); // delete the product ion experiment. We will be adding one for each precursor ion in the transition list. period.DeleteExperiment(1); break; case 1: prodIonExperiment = (Experiment)period.GetExperiment(0); // delete the product ion experiment. We will be adding one for each precursor ion in the transition list. period.DeleteExperiment(0); break; default: throw new IOException(string.Format("Expected 1 or 2 experiments in the template. Found {0} experiments.", period.ExperimCount)); } int j; if (Ms1Scan) { // If the template does not already have a TOF MS scan add one now. if(tofExperiment == null) { var experiment = (Experiment)period.CreateExperiment(out j); experiment.InitExperiment(); experiment.ScanType = TOF_MS_SCAN; } } if(prodIonExperiment == null) { throw new IOException("Product Ion scan was not found in the method."); } // Get the TOF mass range from the template var tofPropertiesTemplate = (ITOFProperties)prodIonExperiment; short s; //Get initial source parameters from the template var sourceParamsTblInput = (ParamDataColl)prodIonExperiment.SourceParamsTbl; ParameterData param = (ParameterData) sourceParamsTblInput.FindParameter("GS1", out s); float sourceGas1 = param == null ? 0 : param.startVal; param = (ParameterData)sourceParamsTblInput.FindParameter("GS2", out s); float sourceGas2 = param == null ? 0 : param.startVal; param = (ParameterData)sourceParamsTblInput.FindParameter("CUR", out s); float curtainGas = param == null ? 0 : param.startVal; param = (ParameterData)sourceParamsTblInput.FindParameter("TEM", out s); float temperature = param == null ? 0 : param.startVal; param = (ParameterData)sourceParamsTblInput.FindParameter("IHT", out s); float nanoTemperature = param == null ? 0 : param.startVal; string ionSprayVoltageParamName = "ISVF"; // ISVF on 5600, IS on QSTAR float ionSprayVoltage; var paramData = ((ParameterData)sourceParamsTblInput.FindParameter(ionSprayVoltageParamName, out s)); if (s != -1) { ionSprayVoltage = paramData.startVal; } else { ionSprayVoltageParamName = "IS"; ionSprayVoltage = ((ParameterData)sourceParamsTblInput.FindParameter(ionSprayVoltageParamName, out s)).startVal; } // We will use parameters from the first mass range in the template product ion experiment. var massRangeTemplate = (IMassRange)prodIonExperiment.GetMassRange(0); var paramTblTemplate = (ParamDataColl)massRangeTemplate.MassDepParamTbl; double minPrecursorMass = double.MaxValue; double maxPrecursorMass = 0; var precursorsToExperimentIndex = new Dictionary<double, int>(); foreach (var transition in transitions.Transitions) { if (precursorsToExperimentIndex.ContainsKey(transition.PrecursorMz)) { transition.ExperimentIndex = IsPrecursorTypeTransition(transition) ? 0 : precursorsToExperimentIndex[transition.PrecursorMz]; continue; } var experiment = (Experiment) period.CreateExperiment(out j); precursorsToExperimentIndex.Add(transition.PrecursorMz, j); transition.ExperimentIndex = IsPrecursorTypeTransition(transition) ? 0 : j; experiment.InitExperiment(); // Setting ScanType to 6 for QSTAR causes method export to fail. Setting it to 9 works for both AB 5600 and QSTAR experiment.ScanType = PROD_ION_SCAN; experiment.FixedMass = transition.PrecursorMz; minPrecursorMass = Math.Min(minPrecursorMass, transition.PrecursorMz); maxPrecursorMass = Math.Max(maxPrecursorMass, transition.PrecursorMz); var tofProperties = (ITOFProperties)experiment; tofProperties.AccumTime = tofPropertiesTemplate.AccumTime; tofProperties.TOFMassMin = tofPropertiesTemplate.TOFMassMin; tofProperties.TOFMassMax = tofPropertiesTemplate.TOFMassMax; // The following should trigger the "Suggest" button functionality // of updating the Q2 transmission window. tofProperties.UseQ1TranDefault = 1; //tofProperties.UseTOFExtrDefault = 1; // Works without this one. // High Sensitivity vs. High Resolution var tofProperties2 = experiment as ITOFProperties2; var templateTofProperties2 = prodIonExperiment as ITOFProperties2; if (tofProperties2 != null && templateTofProperties2 != null) { tofProperties2.HighSensitivity = templateTofProperties2.HighSensitivity; } var sourceParamsTblOutput = (ParamDataColl)experiment.SourceParamsTbl; if (sourceParamsTblInput.FindParameter("GS1", out s) != null && s != -1) sourceParamsTblOutput.AddSetParameter("GS1", sourceGas1, sourceGas1, 0, out s); if (sourceParamsTblInput.FindParameter("GS2", out s) != null && s != -1) sourceParamsTblOutput.AddSetParameter("GS2", sourceGas2, sourceGas2, 0, out s); if (sourceParamsTblInput.FindParameter("CUR", out s) != null && s != -1) sourceParamsTblOutput.AddSetParameter("CUR", curtainGas, curtainGas, 0, out s); if (sourceParamsTblInput.FindParameter("TEM", out s) != null && s != -1) sourceParamsTblOutput.AddSetParameter("TEM", temperature, temperature, 0, out s); if (sourceParamsTblInput.FindParameter("IHT", out s) != null && s != -1) sourceParamsTblOutput.AddSetParameter("IHT", nanoTemperature, nanoTemperature, 0, out s); if (sourceParamsTblInput.FindParameter(ionSprayVoltageParamName, out s) != null && s != -1) sourceParamsTblOutput.AddSetParameter(ionSprayVoltageParamName, ionSprayVoltage, ionSprayVoltage, 0, out s); // Copy the compound dependent parameters from the template for (int i = 0; i < experiment.MassRangesCount; i++) { var massRange = (IMassRange)experiment.GetMassRange(i); var massDepParams = (ParamDataColl)massRange.MassDepParamTbl; // Declustering potential float dp = ((ParameterData)paramTblTemplate.FindParameter("DP", out s)).startVal; if(s != -1) { if (transition.DP > 0) dp = Convert.ToSingle(transition.DP); massDepParams.AddSetParameter("DP", dp, dp, 0, out s); } // Collision engergy float ce = ((ParameterData)paramTblTemplate.FindParameter("CE", out s)).startVal; if (s != -1) { if (transition.CE > 0) ce = Convert.ToSingle(transition.CE); massDepParams.AddSetParameter("CE", ce, ce, 0, out s); } // Ion release delay float ird = ((ParameterData)paramTblTemplate.FindParameter("IRD", out s)).startVal; if (s != -1) { massDepParams.AddSetParameter("IRD", ird, ird, 0, out s); } // Ion release width float irw = ((ParameterData)paramTblTemplate.FindParameter("IRW", out s)).startVal; if (s != -1) { massDepParams.AddSetParameter("IRW", irw, irw, 0, out s); } // Collision energy spread; Only on the Analyst TF 1.5.1 and TF1.5.2 paramData = ((ParameterData)paramTblTemplate.FindParameter("CES", out s)); if (s != -1) { massDepParams.AddSetParameter("CES", paramData.startVal, paramData.startVal, 0, out s); } // Focusing potential; Only on Analyst QS 2.0 paramData = ((ParameterData)paramTblTemplate.FindParameter("FP", out s)); if (s != -1) { massDepParams.AddSetParameter("FP", paramData.startVal, paramData.startVal, 0, out s); } // Declustering potential 2; Only on Analyst QS 2.0 paramData = ((ParameterData)paramTblTemplate.FindParameter("DP2", out s)); if (s != -1) { massDepParams.AddSetParameter("DP2", paramData.startVal, paramData.startVal, 0, out s); } // Collision gas; Only on Analyst QS 2.0 paramData = ((ParameterData)paramTblTemplate.FindParameter("CAD", out s)); if (s != -1) { massDepParams.AddSetParameter("CAD", paramData.startVal, paramData.startVal, 0, out s); } } } // Expand the mass range for the TOF MS scan if the precursor mass of any of the MS/MS experiments // was out of the range if(Ms1Scan) { var ms1TofProperties = (ITOFProperties)(period.GetExperiment(0)); ms1TofProperties.TOFMassMin = Math.Min(ms1TofProperties.TOFMassMin, minPrecursorMass); ms1TofProperties.TOFMassMax = Math.Max(ms1TofProperties.TOFMassMax, maxPrecursorMass); } }
private void ValidateMethod(MassSpecMethod method) { if (method == null) { throw new IOException(string.Format("Failed to open template method {0}. " + "The given template may be invalid for the available version of Analyst.", TemplateMethod)); } if (method.PeriodCount != 1) { throw new IOException(string.Format("Invalid template method {0}. Expecting only one period.", TemplateMethod)); } var period = (Period) method.GetPeriod(0); var experimentCount = period.ExperimCount; if (InclusionList || ScheduledMethod) { if(!IsDataDependentMethod(method)) { throw new IOException(string.Format("Invalid template method for an IDA or Scheduled experiment {0}. "+ "Template does not support inclusion lists.", TemplateMethod)); } // A valid IDA method will have at least one TOF MS scan and one Product Ion scan // On the 5600 (Analyst TF1.5)we can have 1 or 2 TOF MS scans followed by 1 Product Ion scan // On the QSTAR (Analyst 2.0) we should have 1 TOF MS scan followed by 1 or more Product Ion scans if (experimentCount < 2) throw new IOException(string.Format("Invalid template method for an IDA or Scheduled experiment {0}. " + "Template must have one or two TOF MS experiments and at least one Product Ion experiment.", TemplateMethod)); // get the first experiment, it should be a TOF MS experiment var msExperiment = (Experiment) period.GetExperiment(0); if (!IsTofMsScan(msExperiment)) throw new IOException(string.Format("Invalid template method for an IDA or Scheduled experiment {0}. " + "First experiment type must be TOF MS.", TemplateMethod)); // get the last experiment, it should be a Product ion experiment msExperiment = ((Experiment)period.GetExperiment(experimentCount -1)); if (!IsProductIonScan(msExperiment)) throw new IOException(string.Format("Invalid template method for an IDA or Scheduled experiment {0}. " + "Last experiment type must be Product Ion Scan.", TemplateMethod)); } else { if (IsDataDependentMethod(method)) { throw new IOException(string.Format("Invalid template method for a targeted MS/MS experiment {0}. "+ "The given template is for a data dependent experiment.", TemplateMethod)); } if (experimentCount != 1 && experimentCount != 2) { throw new IOException(string.Format("Invalid template method for a targeted MS/MS experiment {0}. " + "Template must have 1 or 2 experiments.", TemplateMethod)); } // If the template has 1 experiment it should be a Product Ion experiment if(experimentCount == 1) { var msExperiment = (Experiment)period.GetExperiment(0); if (!IsProductIonScan(msExperiment)) throw new IOException(string.Format("Invalid template method for a targeted MS/MS experiment {0}. "+ "Template does not have a Product Ion Scan.", TemplateMethod)); } // If the template has 2 experiments require the first one to be a TOF MS and the second one to be a Product Ion if(experimentCount == 2) { var msExperiment = (Experiment)period.GetExperiment(0); if (!IsTofMsScan(msExperiment)) throw new IOException(string.Format("Invalid template method for a targeted MS/MS experiment {0}. "+ "Template has 2 experiments. First experiment type must be TOF MS.", TemplateMethod)); msExperiment = (Experiment)period.GetExperiment(1); if (!IsProductIonScan(msExperiment)) throw new IOException(string.Format("Invalid template method for a targeted MS/MS experiment {0}. "+ "Template has 2 experiments. Second experiment type must be Product Ion Scan.", TemplateMethod)); } } }
private static bool IsDataDependentMethod(MassSpecMethod method) { return ((IMassSpecMethod2) method).DataDependent == 1; }
internal static IAcqMethod GetAcqMethod(string methodFilePath, out MassSpecMethod templateMsMethod) { ApplicationClass analyst = new ApplicationClass(); // Make sure that Analyst is fully started IAcqMethodDirConfig acqMethodDir = (IAcqMethodDirConfig)analyst.Acquire(); if (acqMethodDir == null) { throw new IOException("Failed to initialize. Analyst may need to be started."); } object acqMethodObj; acqMethodDir.LoadNonUIMethod(methodFilePath, out acqMethodObj); IAcqMethod templateAcqMethod = (IAcqMethod)acqMethodObj; templateMsMethod = ExtractMsMethod(templateAcqMethod); return templateAcqMethod; }
// read the updated method and make sure that the inclusion list is in the method private void TestIDACommon(string methodFilePath, bool isScheduled) { MassSpecMethod myMethod = GetMethod(methodFilePath); // The method should have an inclusion list object idaServer; ((IMassSpecMethod2)myMethod).GetDataDependSvr(out idaServer); var useInclusionList = 0; ((IDDEMethodObj)idaServer).getUseIncludeList(ref useInclusionList); Assert.AreEqual(1, useInclusionList); // The inclusion list should have 20 entries. int inclusionListSize = 0; ((IDDEMethodObj)idaServer).GetIonListSize(1, ref inclusionListSize); Assert.AreEqual(20, inclusionListSize); // test m/z for the first entry in the inclusion list double mz = 0; ((IDDEMethodObj)idaServer).GetIncludeIonEntry(0, ref mz); Assert.AreEqual(744.839753, mz); // test m/z the last entry in the inclusion list ((IDDEMethodObj)idaServer).GetIncludeIonEntry(19, ref mz); Assert.AreEqual(572.791863, mz); // test retention time if (isScheduled) { // Since this is an scheduled method, the retention time of each entry should be a non-zero value double rt = -1; ((IDDEMethodObj3)idaServer).GetIncludeRetTimeEntry(0, ref rt); Assert.AreEqual(19.49, rt); ((IDDEMethodObj3)idaServer).GetIncludeRetTimeEntry(19, ref rt); Assert.AreEqual(20.48, rt); double exceedCountSwitch = -1; ((IDDEMethodObj)idaServer).getExceedCountSwitch(ref exceedCountSwitch); Assert.AreEqual(2000000, exceedCountSwitch); double intensityThreshold = -1; ((IDDEMethodObj)idaServer).getIntensityThreshold(ref intensityThreshold); Assert.AreEqual(0, intensityThreshold); int spectraSwicth = -1; ((IDDEMethodObj)idaServer).getSpectraSwitch(ref spectraSwicth); Assert.AreEqual(12, spectraSwicth); } else { // Since this is an unscheduled method the retention time of each entry should // be set to 0 double rt = -1; ((IDDEMethodObj3)idaServer).GetIncludeRetTimeEntry(0, ref rt); Assert.AreEqual(0, rt); ((IDDEMethodObj3)idaServer).GetIncludeRetTimeEntry(19, ref rt); Assert.AreEqual(0, rt); } DeleteOutput(methodFilePath); }