/// <summary>
 /// Clear the graph and track new status object.
 /// </summary>
 /// <param name="status"></param>
 public void ClearGraph(ChromatogramLoadingStatus status)
 {
     _newStatus = status;
 }
        /// <summary>
        /// Add peaks to the graph.
        /// </summary>
        /// <returns>True if render is needed.</returns>
        private bool AddData(ChromatogramLoadingStatus.TransitionData transitions)
        {
            List<ChromatogramLoadingStatus.TransitionData.Peak> bin;
            bool peaksAdded = false;

            // Process bins of peaks queued by the reader thread.
            float maxTime = (float) Math.Max(Math.Max(_xMax, transitions.MaxRetentionTime), transitions.CurrentTime);
            float maxIntensity = 0;
            while (transitions.BinnedPeaks.TryPeek(out bin))
            {
                transitions.BinnedPeaks.TryDequeue(out bin);

                if (bin == null)
                {
                    ResetGraph();
                    maxTime = (float) _xMax;
                    maxIntensity = 0;
                    transitions.MaxIntensity = 0;
                    continue;
                }

                if (transitions.Progressive)
                    ProcessBinProgressive(bin, ref peaksAdded, ref maxTime, ref maxIntensity);
                else
                    ProcessBinSRM(bin, ref peaksAdded, ref maxTime, ref maxIntensity);

                transitions.MaxIntensity = Math.Max(transitions.MaxIntensity, maxIntensity);
            }

            // Rescale graph if necessary.
            if (_xMax <= X_AXIS_START)
            {
                _xMax = maxTime;
                _xAxisAnimation = new Animation(_graphPane.XAxis.Scale.Max, _xMax, 1, FAST_FRAME_MILLISECONDS);
            }
            else if (_xMax < maxTime)
            {
                _xMax = maxTime * 1.1;
                _xAxisAnimation = new Animation(_graphPane.XAxis.Scale.Max, _xMax, STEPS_FOR_TIME_AXIS_ANIMATION,
                    FAST_FRAME_MILLISECONDS);
            }

            if (_yMax < maxIntensity)
            {
                _yMax = maxIntensity*1.1;
                _yAxisAnimation = new Animation(_graphPane.YAxis.Scale.Max, _yMax, STEPS_FOR_INTENSITY_ANIMATION);
            }

            return peaksAdded;
        }
        /// <summary>
        /// Render the graph on the background thread.
        /// </summary>
        /// <param name="bitmap">Destination bitmap.</param>
        /// <param name="fullFrame">True to force full frame rendering.</param>
        protected override Rectangle Render(Bitmap bitmap, bool fullFrame)
        {
            _fullFrame = fullFrame;

            var newStatus = Interlocked.Exchange(ref _newStatus, null);
            if (newStatus != null)
            {
                _status = newStatus;
                ResetGraph();
            }

            if (_status == null)
                return Rectangle.Empty;

            // We need to process data even if the control isn't visible to reduce
            // the memory load of raw chromatogram data.
            bool newPeaks = false;
            double time = _lastTime;
            bool progressive = false;
            if (_status.Transitions != null)
            {
                progressive = _status.Transitions.Progressive;
                time = _status.Transitions.CurrentTime;
                newPeaks = AddData(_status.Transitions);
            }

            if (!IsVisible)
                return Rectangle.Empty;

            Rectangle invalidRect;
            if (_fullFrame || _xAxisAnimation != null || _yAxisAnimation != null || (newPeaks && !progressive) || time < _lastTime)
            {
                // full frame invalidation
                invalidRect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            }
            else if (newPeaks || time > _lastTime)
            {
                var p1 = _graphPane.GeneralTransform(_lastTime, 0, CoordType.AxisXYScale);
                var p2 = _graphPane.GeneralTransform(time, 0, CoordType.AxisXYScale);
                int x = (int) p1.X - 1;
                int y = 0;
                int width = (int)(p2.X + PROGRESS_LINE_WIDTH) - x;
                int height = (int) p1.Y + 2;
                invalidRect = new Rectangle(x, y, width, height);
            }
            else
            {
                invalidRect = Rectangle.Empty;
            }

            // Animate changing axis scales.
            Animate();

            // For progressive import, update the progress line.
            if (progressive)
            {
                _lastTime = time;
                UpdateProgressLine(time);
                if (_unfinishedBox == null)
                    invalidRect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            }

            // Render a new bitmap if something has changed.
            if (invalidRect.Width > 0 && _status.Transitions != null &&
                (_status.Transitions.CurrentTime > 0 || _status.Transitions.MaxRetentionTime > 0))
            {
                using (var graphics = Graphics.FromImage(bitmap))
                {
                    graphics.SetClip(invalidRect);
                    _graphPane.ReSize(graphics, new RectangleF(0, 0, bitmap.Width, bitmap.Height));
                    _graphPane.Draw(graphics);
                }
            }

            return invalidRect;
        }
 public ChromDataCollectorSet(ChromSource chromSource, TimeSharing timeSharing,
     ChromatogramLoadingStatus.TransitionData allChromData, BlockWriter blockWriter)
 {
     ChromSource = chromSource;
     TypeOfScans = timeSharing;
     PrecursorCollectorMap = new List<Tuple<PrecursorTextId, ChromDataCollector>>();
     if (timeSharing == TimeSharing.shared)
     {
         SharedTimesCollector = new SortedBlockedList<float>();
         ScanIdsCollector = new BlockedList<int>();
     }
     _allChromData = allChromData;
     _blockWriter = blockWriter;
 }
            public Spectra(SrmDocument document, SpectrumFilter filter, ChromatogramLoadingStatus.TransitionData allChromData, MsDataFileImpl dataFile)
            {
                _document = document;
                _filter = filter;
                _dataFile = dataFile;

                _allChromData = allChromData;

                _lookaheadContext = new LookaheadContext(_filter, _dataFile);
                _countSpectra = dataFile.SpectrumCount;

                HasSrmSpectra = dataFile.HasSrmSpectra;

                // If possible, find the maximum retention time in order to scale the chromatogram graph.
                if (_allChromData != null && (_filter.EnabledMsMs || _filter.EnabledMs))
                {
                    var retentionTime = _dataFile.GetStartTime(_countSpectra - 1);
                    if (retentionTime.HasValue)
                    {
                        _allChromData.MaxRetentionTime = (float)retentionTime.Value;
                        _allChromData.MaxRetentionTimeKnown = true;
                        _allChromData.Progressive = true;
                    }
                }
            }
        /// <summary>
        /// Display chromatogram data. 
        /// </summary>
        /// <param name="status"></param>
        public void UpdateStatus(ChromatogramLoadingStatus status)
        {
            // Update progress bars and progress labels.
            var fileCount = Math.Max(1, status.SegmentCount - 1);

            // Update file label.
            if (status.Segment == status.SegmentCount-1)
            {
                lblFileName.Visible = false;
                progressBarFile.Visible = false;
                lblFileCount.Text = Resources.AllChromatogramsGraph_UpdateStatus_Joining_chromatograms___;
            }
            else
            {
                progressBarFile.Value = status.ZoomedPercentComplete;

                // Clear graph when a new file starts loading.
                if (null != status.FilePath && _currentFilePath != status.FilePath)
                {
                    _currentFilePath = status.FilePath;
            //                    LOG.Info("Showing " + _currentFilePath);    // Not L10N
                    lblFileName.Text = status.FilePath.GetFileName() + status.FilePath.GetSampleName();
                    asyncGraph.ClearGraph(status);
                }

                lblFileCount.Text = string.Format(Resources.AllChromatogramsGraph_UpdateStatus__0__of__1__files, status.Segment + 1, fileCount);
            }

            // Show multi-file progress bar if we have more than one file to import.
            if (fileCount != 1)
            {
                if (Visible && !panelMultifileProgress.Visible)
                {
                    panelMultifileProgress.Visible = true;
                    panelFileProgress.Top -= _adjustLayoutForMultifile;
                    panelGraph.Height -= _adjustLayoutForMultifile;
                    // TODO: uncomment this when single file cancellation works
                    //btnCancelFile.Visible = true;
                }
                progressBarAllFiles.Value = status.PercentComplete;
            }

            // Show warning message if necessary.
            if (status.WarningMessage != null)
            {
                lblWarning.Text = status.WarningMessage;
                lblWarning.Visible = true;
                asyncGraph.Height = lblWarning.Top - 7;
            }
            else
            {
                lblWarning.Visible = false;
                asyncGraph.Height = panelFileProgress.Top - 7;
            }

            lblDuration.Text = _stopwatch.Elapsed.ToString(@"hh\:mm\:ss"); // Not L10N
        }