43 qRegisterMetaType<pappso::BasePlotContext>(
"pappso::BasePlotContext");
45 qRegisterMetaType<pappso::BasePlotContext *>(
"pappso::BasePlotContext *");
52 qFatal(
"Programming error.");
55 m_pen.setStyle(Qt::SolidLine);
56 m_pen.setBrush(Qt::black);
76 qFatal(
"Programming error.");
110 const QString &x_axis_label,
111 const QString &y_axis_label)
116 if(parent ==
nullptr)
117 qFatal(
"Programming error.");
120 m_pen.setStyle(Qt::SolidLine);
121 m_pen.setBrush(Qt::black);
124 xAxis->setLabel(x_axis_label);
125 yAxis->setLabel(y_axis_label);
144 qFatal(
"Programming error.");
177 for(
int iter = 0; iter < layerCount(); ++iter)
180 QString(
"Layer index %1: %2\n").arg(iter).arg(layer(iter)->name());
189 if(layerable_p ==
nullptr)
190 qFatal(
"Programming error.");
192 QCPLayer *layer_p = layerable_p->layer();
194 return layer_p->name();
200 if(layerable_p ==
nullptr)
201 qFatal(
"Programming error.");
203 QCPLayer *layer_p = layerable_p->layer();
205 for(
int iter = 0; iter < layerCount(); ++iter)
207 if(layer(iter) == layer_p)
229 pen.setColor(QColor(
"steelblue"));
254 pen.setColor(QColor(
"green"));
265 pen.setColor(QColor(
"red"));
296 pen.setColor(
"steelblue");
361 "plotsLayer", layer(
"background"), QCustomPlot::LayerInsertMode::limAbove);
363 addLayer(
"labelsLayer", layer(
"background"), QCustomPlot::LayerInsertMode::limAbove);
368 setFocusPolicy(Qt::StrongFocus);
369 setInteractions(QCP::iRangeZoom | QCP::iSelectPlottables | QCP::iMultiSelect);
379 &QCustomPlot::mouseRelease,
387 &QCustomPlot::axisDoubleClick,
391 connect(
this, &QCustomPlot::beforeReplot,
this, [&]() { emit
beforeReplotSignal(); });
392 connect(
this, &QCustomPlot::afterLayout,
this, [&]() { emit
afterLayoutSignal(); });
393 connect(
this, &QCustomPlot::afterReplot,
this, [&]() { emit
afterReplotSignal(); });
412 const QColor &new_color)
414 if(plottable_p ==
nullptr)
415 qFatal(
"Pointer cannot be nullptr.");
420 pen = plottable_p->pen();
421 pen.setColor(new_color);
422 plottable_p->setPen(pen);
430 if(!new_color.isValid())
433 QCPGraph *graph_p = graph(index);
435 if(graph_p ==
nullptr)
436 qFatal(
"Programming error.");
444 if(plottable_p ==
nullptr)
445 qFatal(
"Programming error.");
447 return plottable_p->pen().color();
453 QCPGraph *graph_p = graph(index);
455 if(graph_p ==
nullptr)
456 qFatal(
"Programming error.");
464 xAxis->setLabel(label);
470 yAxis->setLabel(label);
568 qFatal(
"Programming error.");
612 m_context.m_pressedKeyCode =
event->key();
613 m_context.m_keyboardModifiers = QGuiApplication::queryKeyboardModifiers();
615 if(event->key() == Qt::Key_Left || event->key() == Qt::Key_Right ||
616 event->key() == Qt::Key_Up || event->key() == Qt::Key_Down)
637 m_context.m_releasedKeyCode =
event->key();
642 m_context.m_keyboardModifiers = QGuiApplication::queryKeyboardModifiers();
645 if(event->key() == Qt::Key_Backspace)
654 else if(event->key() == Qt::Key_Space)
658 else if(event->key() == Qt::Key_Delete)
671 int graph_count = plottableCount();
694 QList<QCPGraph *> selected_graph_list;
696 selected_graph_list = selectedGraphs();
698 if(!selected_graph_list.size())
707 for(
int iter = 0; iter < selected_graph_list.size(); ++iter)
714 this, selected_graph_list.at(iter),
m_context);
727 else if(event->key() == Qt::Key_T)
739 else if(event->key() == Qt::Key_Left || event->key() == Qt::Key_Right ||
740 event->key() == Qt::Key_Up || event->key() == Qt::Key_Down)
749 else if(event->key() == Qt::Key_S)
767 m_context.m_integrationScopeRhombWidth = 0;
768 m_context.m_integrationScopeRhombHeight = abs(
780 m_context.m_integrationScopeRhombWidth = abs(
782 m_context.m_integrationScopeRhombHeight = 0;
819 int pixel_increment = 0;
821 if(
m_context.m_keyboardModifiers == Qt::NoModifier)
823 else if(
m_context.m_keyboardModifiers == Qt::AltModifier)
824 pixel_increment = 50;
830 if(event->key() == Qt::Key_Left)
832 else if(event->key() == Qt::Key_Right)
834 else if(event->key() == Qt::Key_Up)
836 else if(event->key() == Qt::Key_Down)
851 [[maybe_unused]] QKeyEvent *event)
860 QPointF pixel_coordinates(
861 xAxis->coordToPixel(
m_context.m_lastCursorHoveredPoint.x()),
862 yAxis->coordToPixel(
m_context.m_lastCursorHoveredPoint.y()));
864 Qt::MouseButton button = Qt::NoButton;
865 QEvent::Type q_event_type = QEvent::MouseButtonPress;
871 button = Qt::LeftButton;
873 m_context.m_isLeftPseudoButtonKeyPressed =
874 !
m_context.m_isLeftPseudoButtonKeyPressed;
876 if(
m_context.m_isLeftPseudoButtonKeyPressed)
877 q_event_type = QEvent::MouseButtonPress;
879 q_event_type = QEvent::MouseButtonRelease;
885 button = Qt::RightButton;
887 m_context.m_isRightPseudoButtonKeyPressed =
888 !
m_context.m_isRightPseudoButtonKeyPressed;
890 if(
m_context.m_isRightPseudoButtonKeyPressed)
891 q_event_type = QEvent::MouseButtonPress;
893 q_event_type = QEvent::MouseButtonRelease;
901 QMouseEvent *mouse_event_p =
902 new QMouseEvent(q_event_type,
904 mapToGlobal(pixel_coordinates.toPoint()),
905 mapToGlobal(pixel_coordinates.toPoint()),
909 Qt::MouseEventSynthesizedByApplication);
911 if(q_event_type == QEvent::MouseButtonPress)
916 delete mouse_event_p;
943 QPointF mousePoint =
event->position();
947 m_context.m_lastCursorHoveredPoint.setX(xAxis->pixelToCoord(mousePoint.x()));
948 m_context.m_lastCursorHoveredPoint.setY(yAxis->pixelToCoord(mousePoint.y()));
958 if(
m_context.m_pressedMouseButtons & Qt::LeftButton ||
959 m_context.m_pressedMouseButtons & Qt::RightButton)
1005 xAxis->range().lower,
m_context.m_lastCursorHoveredPoint.y());
1007 xAxis->range().upper,
m_context.m_lastCursorHoveredPoint.y());
1018 m_context.m_lastCursorHoveredPoint.x(), yAxis->range().upper);
1020 m_context.m_lastCursorHoveredPoint.x(), yAxis->range().lower);
1041 m_context.m_keyboardModifiers = QGuiApplication::queryKeyboardModifiers();
1059 yAxis->range().upper);
1062 yAxis->range().lower);
1105 if(
m_context.m_mouseButtonsAtMousePress & Qt::LeftButton)
1109 else if(
m_context.m_mouseButtonsAtMousePress & Qt::RightButton)
1127 m_context.m_isMeasuringDistance =
false;
1136 if(
m_context.m_keyboardModifiers & Qt::ControlModifier)
1158 if(
m_context.m_pressedKeyCode == Qt::Key_Q)
1261 m_context.m_isMeasuringDistance =
false;
1308 QPointF mousePoint =
event->position();
1310 m_context.m_lastPressedMouseButton =
event->button();
1311 m_context.m_mouseButtonsAtMousePress =
event->buttons();
1315 m_context.m_pressedMouseButtons |=
event->button();
1390 m_context.m_startDragPoint.setX(xAxis->pixelToCoord(mousePoint.x()));
1391 m_context.m_startDragPoint.setY(yAxis->pixelToCoord(mousePoint.y()));
1401 m_context.m_lastCursorHoveredPoint.x(), yAxis->range().upper);
1403 m_context.m_lastCursorHoveredPoint.x(), yAxis->range().lower);
1422 m_context.m_lastReleasedMouseButton =
event->button();
1427 m_context.m_mouseButtonsAtMouseRelease =
event->buttons();
1431 m_context.m_pressedMouseButtons ^=
event->button();
1437 m_context.m_keyboardModifiers = QGuiApplication::keyboardModifiers();
1467 m_context.m_lastCursorHoveredPoint.y());
1469 m_context.m_lastCursorHoveredPoint.y());
1476 yAxis->range().upper);
1478 yAxis->range().lower);
1500 if(
m_context.m_lastReleasedMouseButton == Qt::LeftButton)
1504 else if(
m_context.m_lastReleasedMouseButton == Qt::RightButton)
1595 if(
m_context.m_keyboardModifiers & Qt::ControlModifier)
1632 double x_delta_pixel =
1633 fabs(xAxis->coordToPixel(
m_context.m_currentDragPoint.x()) -
1634 xAxis->coordToPixel(
m_context.m_startDragPoint.x()));
1636 if(x_delta_pixel > 3)
1651 m_context.m_xRange = QCPRange(xAxis->range());
1652 m_context.m_yRange = QCPRange(yAxis->range());
1668 [[maybe_unused]] QCPAxis::SelectablePart part,
1673 m_context.m_keyboardModifiers = QGuiApplication::queryKeyboardModifiers();
1675 if(
m_context.m_keyboardModifiers & Qt::ControlModifier)
1704 m_context.m_pressedMouseButtons ^=
event->button();
1716 QCPLayoutElement *layoutElement = layoutElementAt(mousePoint);
1719 layoutElement ==
dynamic_cast<QCPLayoutElement *
>(axisRect()))
1725 QCPAxis::SelectablePart selectablePart;
1727 selectablePart = xAxis->getPartAt(mousePoint);
1729 if(selectablePart == QCPAxis::spAxisLabel ||
1730 selectablePart == QCPAxis::spAxis ||
1731 selectablePart == QCPAxis::spTickLabels)
1741 QCPLayoutElement *layoutElement = layoutElementAt(mousePoint);
1744 layoutElement ==
dynamic_cast<QCPLayoutElement *
>(axisRect()))
1750 QCPAxis::SelectablePart selectablePart;
1752 selectablePart = yAxis->getPartAt(mousePoint);
1754 if(selectablePart == QCPAxis::spAxisLabel ||
1755 selectablePart == QCPAxis::spAxis ||
1756 selectablePart == QCPAxis::spTickLabels)
1781 double x_delta_pixel =
1782 fabs(xAxis->coordToPixel(
m_context.m_currentDragPoint.x()) -
1783 xAxis->coordToPixel(
m_context.m_startDragPoint.x()));
1785 double y_delta_pixel =
1786 fabs(yAxis->coordToPixel(
m_context.m_currentDragPoint.y()) -
1787 yAxis->coordToPixel(
m_context.m_startDragPoint.y()));
1789 if(x_delta_pixel > y_delta_pixel)
1790 return Qt::Horizontal;
1792 return Qt::Vertical;
1800 QPointF pixels_coordinates(xAxis->coordToPixel(graph_coordinates.x()),
1801 yAxis->coordToPixel(graph_coordinates.y()));
1810 QCursor::setPos(mapToGlobal(pixel_coordinates.toPoint()));
1818 QPointF pixel_coord(xAxis->coordToPixel(graph_coord.x()),
1819 yAxis->coordToPixel(graph_coord.y()));
1831 QPointF pixel_coordinates(
1832 xAxis->coordToPixel(
m_context.m_lastCursorHoveredPoint.x()) + pixel_count,
1833 yAxis->coordToPixel(
m_context.m_lastCursorHoveredPoint.y()));
1837 QPointF graph_coordinates(xAxis->pixelToCoord(pixel_coordinates.x()),
1838 yAxis->pixelToCoord(pixel_coordinates.y()));
1840 return graph_coordinates;
1849 QPointF pixel_coord(xAxis->coordToPixel(graph_coord.x()),
1850 yAxis->coordToPixel(graph_coord.y()));
1862 QPointF pixel_coordinates(
1863 xAxis->coordToPixel(
m_context.m_lastCursorHoveredPoint.x()),
1864 yAxis->coordToPixel(
m_context.m_lastCursorHoveredPoint.y()) + pixel_count);
1868 QPointF graph_coordinates(xAxis->pixelToCoord(pixel_coordinates.x()),
1869 yAxis->pixelToCoord(pixel_coordinates.y()));
1871 return graph_coordinates;
1882 QCPGraph *graph_p = graph(index);
1884 if(graph_p ==
nullptr)
1885 qFatal(
"Programming error.");
1887 return graph_p->getKeyRange(found_range);
1893 QCPGraph *graph_p = graph(index);
1895 if(graph_p ==
nullptr)
1896 qFatal(
"Programming error.");
1898 return graph_p->getValueRange(found_range);
1904 bool &found_range)
const
1913 found_range =
false;
1915 return QCPRange(0, 1);
1918 if(graphCount() == 1)
1919 return graph()->getKeyRange(found_range);
1921 bool found_at_least_one_range =
false;
1924 QCPRange result_range(QCPRange::minRange + 1, QCPRange::maxRange + 1);
1926 for(
int iter = 0; iter < graphCount(); ++iter)
1928 QCPRange temp_range;
1930 bool found_range_for_iter =
false;
1932 QCPGraph *graph_p = graph(iter);
1937 temp_range = graph_p->getKeyRange(found_range_for_iter);
1939 temp_range = graph_p->getValueRange(found_range_for_iter);
1941 qFatal(
"Cannot reach this point. Programming error.");
1946 if(!found_range_for_iter)
1952 if(!QCPRange::validRange(result_range))
1953 qFatal(
"The obtained range is invalid !");
1956 result_range = temp_range;
1959 found_at_least_one_range =
true;
1966 if(temp_range.lower > result_range.lower)
1967 result_range.lower = temp_range.lower;
1968 if(temp_range.upper < result_range.upper)
1969 result_range.upper = temp_range.upper;
1973 if(temp_range.lower < result_range.lower)
1974 result_range.lower = temp_range.lower;
1975 if(temp_range.upper > result_range.upper)
1976 result_range.upper = temp_range.upper;
1979 qFatal(
"Cannot reach this point. Programming error.");
1987 found_range = found_at_least_one_range;
1989 return result_range;
2028 double xLower = xAxis->range().lower;
2029 double xUpper = xAxis->range().upper;
2033 double yLower = yAxis->range().lower;
2034 double yUpper = yAxis->range().upper;
2054 xAxis->setRange(xLower, xUpper -
m_context.m_xDelta);
2064 yAxis->setRange(yLower, yUpper -
m_context.m_yDelta);
2096 yAxis->setRange(xAxis->range().lower,
2097 std::max<double>(
m_context.m_yRegionRangeStart,
2141 "This function can only be called if the mouse click was on one of the "
2176 QCPRange yAxisRange,
2183 xAxis->setRange(xAxisRange.lower, xAxisRange.upper);
2188 yAxis->setRange(yAxisRange.lower, yAxisRange.upper);
2204 xAxis->setRange(lower, upper);
2214 yAxis->setRange(lower, upper);
2274 bool for_integration)
2294 m_context.m_isMeasuringDistance =
false;
2339 QPointF leftmost_point;
2340 if(!
m_context.msp_integrationScope->getLeftMostPoint(leftmost_point))
2341 qFatal(
"Could not get the left-most point.");
2344 if(!
m_context.msp_integrationScope->getWidth(width))
2345 qFatal(
"Could not get width.");
2348 double x_axis_center_position = leftmost_point.x() + width / 2;
2358 int pixels_away_from_line = 15;
2360 QPointF reference_point_for_y_axis_label_position;
2365 if(
static_cast<int>(
m_context.m_dragDirections) &
2374 pixels_away_from_line *= -1;
2376 if(!
m_context.msp_integrationScope->getTopMostPoint(
2377 reference_point_for_y_axis_label_position))
2378 qFatal(
"Failed to get top most point.");
2382 if(!
m_context.msp_integrationScope->getBottomMostPoint(
2383 reference_point_for_y_axis_label_position))
2384 qFatal(
"Failed to get bottom most point.");
2389 double y_axis_pixel_coordinate =
2390 yAxis->coordToPixel(reference_point_for_y_axis_label_position.y());
2394 double y_axis_modified_pixel_coordinate =
2395 y_axis_pixel_coordinate + pixels_away_from_line;
2398 QPointF pixel_coordinates;
2400 pixel_coordinates.setX(x_axis_center_position);
2401 pixel_coordinates.setY(y_axis_modified_pixel_coordinate);
2404 QPointF graph_coordinates(xAxis->pixelToCoord(pixel_coordinates.x()),
2405 yAxis->pixelToCoord(pixel_coordinates.y()));
2412 graph_coordinates.y());
2423 QString label_text = QString(
"full x span %1 -- x drag delta %2")
2424 .arg(width, 0,
'f', decimals)
2425 .arg(fabs(
m_context.m_xDelta), 0,
'f', decimals);
2453 if(!
m_context.msp_integrationScope->getHeight(height))
2454 qFatal(
"Could not get height.");
2471 QPointF bottom_most_point;
2472 if(!
m_context.msp_integrationScope->getBottomMostPoint(bottom_most_point))
2473 qFatal(
"Could not get the bottom-most bottom point.");
2475 double y_axis_center_position = bottom_most_point.y() + height / 2;
2485 int pixels_away_from_line = 15;
2486 double x_axis_coordinate;
2487 double x_axis_pixel_coordinate;
2489 if(
static_cast<int>(
m_context.m_dragDirections) &
2492 QPointF left_most_point;
2494 if(!
m_context.msp_integrationScope->getLeftMostPoint(left_most_point))
2495 qFatal(
"Failed to get left most point.");
2497 x_axis_coordinate = left_most_point.x();
2499 pixels_away_from_line *= -1;
2503 QPointF right_most_point;
2505 if(!
m_context.msp_integrationScope->getRightMostPoint(right_most_point))
2506 qFatal(
"Failed to get right most point.");
2508 x_axis_coordinate = right_most_point.x();
2510 x_axis_pixel_coordinate = xAxis->coordToPixel(x_axis_coordinate);
2512 double x_axis_modified_pixel_coordinate =
2513 x_axis_pixel_coordinate + pixels_away_from_line;
2516 QPointF pixel_coordinates;
2518 pixel_coordinates.setX(x_axis_modified_pixel_coordinate);
2519 pixel_coordinates.setY(y_axis_center_position);
2523 QPointF graph_coordinates(xAxis->pixelToCoord(pixel_coordinates.x()),
2524 yAxis->pixelToCoord(pixel_coordinates.y()));
2527 y_axis_center_position);
2531 QString label_text = QString(
"full y span %1 -- y drag delta %2")
2532 .arg(height, 0,
'f', decimals)
2533 .arg(fabs(
m_context.m_yDelta), 0,
'f', decimals);
2575 double plotHeight = yAxis->range().upper - yAxis->range().lower;
2580 double heightDiffRatio = (heightDiff / plotHeight) * 100;
2582 if(heightDiffRatio > 10)
2601 double x_range_start =
2603 double x_range_end =
2609 double y_position =
m_context.m_startDragPoint.y();
2615 QPointF(x_range_start, y_position));
2640 QPointF(x_range_start, y_position));
2671 QPointF bottom_left_point;
2672 if(!
m_context.msp_integrationScope->getPoint(bottom_left_point))
2673 qFatal(
"Failed to get point.");
2677 if(!
m_context.msp_integrationScope->getWidth(width))
2678 qFatal(
"Failed to get width.");
2682 if(!
m_context.msp_integrationScope->getHeight(height))
2683 qFatal(
"Failed to get height.");
2686 QPointF bottom_right_point(bottom_left_point.x() + width,
2687 bottom_left_point.y());
2690 QPointF top_right_point(bottom_left_point.x() + width,
2691 bottom_left_point.y() + height);
2694 QPointF top_left_point(bottom_left_point.x(), bottom_left_point.y() + height);
2765 scope_features =
m_context.msp_integrationScope->getLeftMostTopPoint(point_1);
2785 qFatal(
"The rhomboid should be horizontal!");
2789 if(!
m_context.msp_integrationScope->getLeftMostTopPoint(point_1))
2790 qFatal(
"Failed to getLeftMostTopPoint.");
2792 if(!
m_context.msp_integrationScope->getRightMostTopPoint(point_2))
2793 qFatal(
"Failed to getRightMostTopPoint.");
2816 if(!
m_context.msp_integrationScope->getRightMostBottomPoint(point_1))
2817 qFatal(
"Failed to getRightMostBottomPoint.");
2825 if(!
m_context.msp_integrationScope->getLeftMostBottomPoint(point_2))
2826 qFatal(
"Failed to getLeftMostBottomPoint.");
2834 if(!
m_context.msp_integrationScope->getLeftMostTopPoint(point_1))
2835 qFatal(
"Failed to getLeftMostTopPoint.");
2877 scope_features =
m_context.msp_integrationScope->getLeftMostTopPoint(point_1);
2897 qFatal(
"The rhomboid should be vertical!");
2902 if(!
m_context.msp_integrationScope->getLeftMostBottomPoint(point_2))
2903 qFatal(
"Failed to getLeftMostBottomPoint.");
2927 if(!
m_context.msp_integrationScope->getRightMostBottomPoint(point_1))
2928 qFatal(
"Failed to getRightMostBottomPoint.");
2937 if(!
m_context.msp_integrationScope->getRightMostTopPoint(point_2))
2938 qFatal(
"Failed to getRightMostTopPoint.");
2947 if(!
m_context.msp_integrationScope->getLeftMostTopPoint(point_1))
2948 qFatal(
"Failed to get the LeftMostTopPoint.");
3017 m_context.updateIntegrationScopeRhomb();
3035 if(
m_context.m_integrationScopeRhombWidth > 0)
3038 else if(
m_context.m_integrationScopeRhombHeight > 0)
3042 qFatal(
"Cannot be both the width or height of rhomboid scope be 0.");
3047 bool for_integration)
3073 if(!(
m_context.m_keyboardModifiers & Qt::AltModifier))
3079 else if(
m_context.m_keyboardModifiers & Qt::AltModifier)
3085 if(!
m_context.m_integrationScopeRhombHeight &&
3086 !
m_context.m_integrationScopeRhombWidth)
3102 std::vector<QPointF> points;
3110 if(
m_context.msp_integrationScope->getPoints(points))
3114 if(!
m_context.msp_integrationScope->getLeftMostPoint(point))
3115 qFatal(
"Failed to get LeftMost point.");
3116 m_context.m_xRegionRangeStart = point.x();
3118 if(!
m_context.msp_integrationScope->getRightMostPoint(point))
3119 qFatal(
"Failed to get RightMost point.");
3120 m_context.m_xRegionRangeEnd = point.x();
3122 else if(
m_context.msp_integrationScope->getHeight(height))
3126 if(!
m_context.msp_integrationScope->getPoint(point))
3127 qFatal(
"Failed to get point.");
3128 m_context.m_xRegionRangeStart = point.x();
3132 if(!
m_context.msp_integrationScope->getWidth(width))
3133 qFatal(
"Failed to get width.");
3137 m_context.m_yRegionRangeStart = point.y();
3139 m_context.m_yRegionRangeEnd = point.y() + height;
3145 if(!
m_context.msp_integrationScope->getPoint(point))
3146 qFatal(
"Failed to get point.");
3147 m_context.m_xRegionRangeStart = point.x();
3151 if(!
m_context.msp_integrationScope->getWidth(width))
3152 qFatal(
"Failed to get width.");
3182 std::const_pointer_cast<IntegrationScopeBase>(
m_context.msp_integrationScope)
3192 int current_selection_polygon =
3197 current_selection_polygon |=
3204 current_selection_polygon |=
3211 current_selection_polygon |=
3218 current_selection_polygon |=
3251 QCustomPlot::setFocus();
3262 if(focusedPlotWidget ==
nullptr)
3264 "baseplotwidget.cpp @ redrawPlotBackground(QWidget *focusedPlotWidget "
3266 "ERROR focusedPlotWidget cannot be nullptr.");
3268 if(
dynamic_cast<QWidget *
>(
this) != focusedPlotWidget)
3287 m_context.m_xRange = QCPRange(xAxis->range().lower, xAxis->range().upper);
3288 m_context.m_yRange = QCPRange(yAxis->range().lower, yAxis->range().upper);
static int zeroDecimalsInValue(pappso_double value)
Determine the number of zero decimals between the decimal point and the first non-zero decimal.
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...