private void WriteScheduledList(FileIterator fileIterator, ICollection <PeptideSchedule> listSchedules) { if (listSchedules.Count == 0) { return; } fileIterator.NextFile(); foreach (var schedule in PeptideSchedule.GetPrecursorSchedules(listSchedules)) { var nodePepGroup = schedule.PeptideGroup; var nodePep = schedule.Peptide; var nodeGroup = schedule.TransitionGroup; var nodeGroupPrimary = schedule.TransitionGroupPrimary; // Write required peptides at the end, like unscheduled methods if (RequiredPeptides.IsRequired(nodePep)) { continue; } // Skip percursors with too few transitions. int groupTransitions = nodeGroup.Children.Count; if (groupTransitions < MinTransitions) { continue; } WriteTransitions(fileIterator, nodePepGroup, nodePep, nodeGroup, nodeGroupPrimary); } fileIterator.WriteRequiredTransitions(this, RequiredPeptides); }
private void BorrowTransitions(PeptideScheduleBucket bucketUnder, PeptideScheduleBucket bucketOver, int balanceCount) { if (!MaxTransitions.HasValue) { throw new InvalidOperationException(Resources.AbstractMassListExporter_ExportScheduledBuckets_Maximum_transitions_per_file_required); } foreach (var schedule in bucketOver.ToArray().RandomOrder()) { // Required peptides may not be removed if (RequiredPeptides.IsRequired(schedule.Peptide)) { continue; } int newOverCount = bucketOver.TransitionCount - schedule.TransitionCount; int newUnderCount = bucketUnder.TransitionCount + schedule.TransitionCount; // If borrowing would not change the balance if ((newOverCount > balanceCount && balanceCount > newUnderCount) || // Or the transfer gets us closer to being balanced Math.Abs(newOverCount - balanceCount) + Math.Abs(newUnderCount - balanceCount) < Math.Abs(bucketOver.Count - balanceCount) + Math.Abs(bucketUnder.Count - balanceCount)) { // Make sure this doesn't exceed the maximum concurrent transition limit. if (schedule.CanAddToBucket(bucketUnder, MaxTransitions.Value)) { bucketOver.Remove(schedule); bucketUnder.Add(schedule); } } // If the over bucket goes below the balance, then quit. if (bucketOver.TransitionCount < balanceCount) { break; } } }
private void ExportScheduledBuckets(FileIterator fileIterator) { if (!MaxTransitions.HasValue) { throw new InvalidOperationException(Resources.AbstractMassListExporter_ExportScheduledBuckets_Maximum_transitions_per_file_required); } bool singleWindow = ExportInstrumentType.IsSingleWindowInstrumentType(InstrumentType); var predict = Document.Settings.PeptideSettings.Prediction; int?maxInstrumentTrans = null; if (!IsPrecursorLimited) { maxInstrumentTrans = Document.Settings.TransitionSettings.Instrument.MaxTransitions; } var listSchedules = new List <PeptideSchedule>(); var listRequired = new List <PeptideSchedule>(); var listUnscheduled = new List <PeptideSchedule>(); foreach (PeptideGroupDocNode nodePepGroup in Document.MoleculeGroups) { foreach (PeptideDocNode nodePep in nodePepGroup.Children) { var peptideSchedule = new PeptideSchedule(nodePep, maxInstrumentTrans); foreach (TransitionGroupDocNode nodeTranGroup in nodePep.Children) { double timeWindow; double retentionTime = predict.PredictRetentionTime(Document, nodePep, nodeTranGroup, SchedulingReplicateIndex, SchedulingAlgorithm, singleWindow, out timeWindow) ?? 0; var nodeTranGroupPrimary = PrimaryTransitionCount > 0 ? nodePep.GetPrimaryResultsGroup(nodeTranGroup) : null; var ps = new PrecursorSchedule(nodePepGroup, nodePep, nodeTranGroup, nodeTranGroupPrimary, retentionTime, timeWindow, IsPrecursorLimited, SchedulingReplicateIndex, PrimaryTransitionCount, OptimizeStepCount); peptideSchedule.Add(ps); } if (RequiredPeptides.IsRequired(nodePep)) { if (!peptideSchedule.CanSchedule) { throw new IOException(string.Format(Resources.AbstractMassListExporter_ExportScheduledBuckets_The_required_peptide__0__cannot_be_scheduled, Document.Settings.GetDisplayName(nodePep))); } listRequired.Add(peptideSchedule); } else if (peptideSchedule.CanSchedule) { listSchedules.Add(peptideSchedule); } else { listUnscheduled.Add(peptideSchedule); } } } int totalScheduled = 0; var listScheduleBuckets = new List <PeptideScheduleBucket>(); while (!PeptideSchedule.IsListScheduled(listSchedules)) { var listScheduleNext = new PeptideScheduleBucket(); // First add all required transitions foreach (var schedule in listRequired) { schedule.Schedule(listScheduleNext, MaxTransitions.Value); } // Then try to add from the scheduling list foreach (var schedule in listSchedules) { schedule.Schedule(listScheduleNext, MaxTransitions.Value); } // Throw an error if nothing beyond the required transitions could be added if (listScheduleNext.TransitionCount == RequiredPeptides.TransitionCount) { string itemName = IsPrecursorLimited ? Resources.AbstractMassListExporter_ExportScheduledBuckets_precursors : Resources.AbstractMassListExporter_ExportScheduledBuckets_transitions; var sb = new StringBuilder(); foreach (var peptideSchedule in listSchedules) { if (peptideSchedule.TransitionCount > MaxTransitions.Value) { sb.AppendLine(string.Format("{0} - {1} {2}", // Not L10N peptideSchedule.Peptide.Peptide, peptideSchedule.TransitionCount, itemName)); } } var message = new StringBuilder(Resources.AbstractMassListExporter_ExportScheduledBuckets_Failed_to_schedule_the_following_peptides_with_the_current_settings); message.AppendLine().AppendLine().AppendLine(sb.ToString()); if (OptimizeStepCount == 0) { message.AppendLine().AppendLine(string.Format(Resources.AbstractMassListExporter_ExportScheduledBuckets_Check_max_concurrent__0__count, itemName)); } else { message.Append(string.Format(Resources.AbstractMassListExporter_ExportScheduledBuckets_Check_max_concurrent__0__count_and_optimization_step_count, itemName)); } throw new IOException(message.ToString()); } listScheduleBuckets.Add(listScheduleNext); totalScheduled += listScheduleNext.TransitionCount; } int countScheduleGroups = listScheduleBuckets.Count; if (countScheduleGroups > 1) { // Balance the scheduling buckets to counteract the tendancy for each // successive bucket to have fewer transitions than the previous. // CONSIDER: O(n^2) but number of groups should never get that large int balanceCount = totalScheduled / countScheduleGroups; for (int i = 0; i < countScheduleGroups; i++) { var bucketUnder = listScheduleBuckets[i]; if (bucketUnder.TransitionCount >= balanceCount) { continue; } // It should not be possible to borrow from scheduling lists // after the current list, since the reason they are there is // that they had too much overlap to be included in any of the // preceding buckets. for (int j = 0; j < i; j++) { var bucketOver = listScheduleBuckets[j]; if (bucketOver.TransitionCount <= balanceCount) { continue; } BorrowTransitions(bucketUnder, bucketOver, balanceCount); // If the under bucket ever goes over balance, then quit. if (bucketUnder.Count > balanceCount) { break; } } } } foreach (var listScheduleNext in listScheduleBuckets) { WriteScheduledList(fileIterator, listScheduleNext); } WriteScheduledList(fileIterator, listUnscheduled); }
private void ExportNormal(FileIterator fileIterator, bool single) { foreach (PeptideGroupDocNode seq in Document.MoleculeGroups) { // Skip peptide groups with no transitions if (seq.TransitionCount == 0) { continue; } if (DocNode is PeptideGroupDocNode && !ReferenceEquals(seq, DocNode)) { continue; } if (Strategy == ExportStrategy.Protein) { fileIterator.Suffix = FileEscape(seq.Name); NextFile(fileIterator); } else if (!single && (!fileIterator.HasFile || (!IgnoreProteins && ExceedsMax(fileIterator.TransitionCount + CalcTransitionCount(seq))))) { NextFile(fileIterator); } foreach (PeptideDocNode peptide in seq.Children) { if (DocNode is PeptideDocNode && !ReferenceEquals(peptide, DocNode)) { continue; } // Required peptides will be written by the NextFile method if (RequiredPeptides.IsRequired(peptide)) { continue; } // Make sure we can write out all the transitions for this peptide. // Never split transitions from a single peptide across multiple injections, // since this would mess up coelution and quantitation. if (!single && fileIterator.TransitionCount > 0 && ExceedsMax(fileIterator.TransitionCount + CalcTransitionCount(peptide))) { NextFile(fileIterator); } foreach (TransitionGroupDocNode group in peptide.Children) { // Skip precursors with too few transitions. int groupTransitions = group.Children.Count; if (groupTransitions < MinTransitions) { continue; } if (DocNode is TransitionGroupDocNode && !ReferenceEquals(group, DocNode)) { continue; } if (IsolationList) { fileIterator.WriteTransition(this, seq, peptide, group, null, null, 0); } else { var groupPrimary = PrimaryTransitionCount > 0 ? peptide.GetPrimaryResultsGroup(group) : null; WriteTransitions(fileIterator, seq, peptide, group, groupPrimary); } } } } // Add the required transitions to the last file fileIterator.WriteRequiredTransitions(this, RequiredPeptides); }