Esempio n. 1
0
    public void InitialiseBends(bool suppress = false)
    {
        AngleConnection angle;
        Bend            bend;

        AngleConnection[] connections = anglesDict.Values.ToArray();
        int numBends = connections.Length;

        int[]    bendAtomNums = new int[numBends * 3];
        double[] bendAEqs     = new double[numBends];
        double[] bendKEqs     = new double[numBends];

        for (int i = 0; i < numBends; i++)
        {
            angle = connections[i];
            bend  = GetBendParameter(angle);
            if (bend == null)
            {
                if (!suppress)
                {
                    throw new NoParameterException(typeof(Bend), angle.atom0, angle.atom1, angle.atom2);
                }
                continue;
            }

            bendAEqs[i]             = Mathf.Deg2Rad * bend.req;
            bendKEqs[i]             = bend.keq;
            bendAtomNums[i * 3]     = angle.atom0.index;
            bendAtomNums[i * 3 + 1] = angle.atom1.index;
            bendAtomNums[i * 3 + 2] = angle.atom2.index;
        }

        Fortran.set_bends(ref numBends, bendAtomNums, bendAEqs, bendKEqs);
    }
Esempio n. 2
0
        public void Modulo()
        {
            Assert.AreEqual(2m, Fortran.Modulo(12m, 5m));
            Assert.AreEqual(2d, Fortran.Modulo(12d, 5d));
            Assert.AreEqual(2f, Fortran.Modulo(12f, 5f));
            Assert.AreEqual(2, Fortran.Modulo(12, 5));
            Assert.AreEqual(2L, Fortran.Modulo(12L, 5L));

            Assert.AreEqual(3m, Fortran.Modulo(-12m, 5m));
            Assert.AreEqual(3d, Fortran.Modulo(-12d, 5d));
            Assert.AreEqual(3f, Fortran.Modulo(-12f, 5f));
            Assert.AreEqual(3, Fortran.Modulo(-12, 5));
            Assert.AreEqual(3L, Fortran.Modulo(-12L, 5L));

            Assert.AreEqual(-3m, Fortran.Modulo(12m, -5m));
            Assert.AreEqual(-3d, Fortran.Modulo(12d, -5d));
            Assert.AreEqual(-3f, Fortran.Modulo(12f, -5f));
            Assert.AreEqual(-3, Fortran.Modulo(12, -5));
            Assert.AreEqual(-3L, Fortran.Modulo(12L, -5L));

            Assert.AreEqual(-2m, Fortran.Modulo(-12m, -5m));
            Assert.AreEqual(-2d, Fortran.Modulo(-12d, -5d));
            Assert.AreEqual(-2f, Fortran.Modulo(-12f, -5f));
            Assert.AreEqual(-2, Fortran.Modulo(-12, -5));
            Assert.AreEqual(-2L, Fortran.Modulo(-12L, -5L));
        }
Esempio n. 3
0
    public void InitialiseMasses()
    {
        int status = 0;

        Fortran.set_masses(atoms.masses, ref status);
        Fortran.CheckStatus(status);
    }
Esempio n. 4
0
    public void InitialiseStretches(bool suppress = false)
    {
        Connection connection;
        Stretch    stretch;

        Connection[] connections  = connectionsDict.Values.ToArray();
        int          numStretches = connections.Length;

        int[]    stretchAtomNums = new int[numStretches * 2];
        double[] stretchREqs     = new double[numStretches];
        double[] stretchKEqs     = new double[numStretches];

        for (int i = 0; i < numStretches; i++)
        {
            connection = connections[i];
            stretch    = GetStretchParameter(connection);
            if (stretch == null)
            {
                if (!suppress)
                {
                    throw new NoParameterException(typeof(Stretch), connection.atom0, connection.atom1);
                }
                continue;
            }

            stretchREqs[i]             = stretch.req;
            stretchKEqs[i]             = stretch.keq;
            stretchAtomNums[i * 2]     = connection.atom0.index;
            stretchAtomNums[i * 2 + 1] = connection.atom1.index;
        }

        Fortran.set_stretches(ref numStretches, stretchAtomNums, stretchREqs, stretchKEqs);
    }
Esempio n. 5
0
        /// <summary>
        /// Converts the specified angle, in degrees, to the nearest <see cref="Compass"/>
        /// direction.</summary>
        /// <param name="degrees">
        /// The angle to convert, in degrees. This value is taken <see cref="Fortran.Modulo"/> 360
        /// degrees, and may therefore be outside the interval [0, 360).</param>
        /// <returns>
        /// The <see cref="Compass"/> direction nearest to the specified <paramref name="degrees"/>.
        /// </returns>
        /// <remarks>
        /// The specified <paramref name="degrees"/> are measured in the same way as <see
        /// cref="Compass"/> directions, i.e. starting at zero for <see cref="Compass.North"/> and
        /// increasing clockwise.</remarks>

        public static Compass DegreesToCompass(double degrees)
        {
            degrees = Fortran.Modulo(degrees + 22.5, 360);
            int point = (int)(degrees / 45);

            return((Compass)(point * 45));
        }
Esempio n. 6
0
        /// <summary>
        /// Gets the <see cref="Brush"/> within the specified <see cref="Array"/> whose index
        /// corresponds to the specified value.</summary>
        /// <param name="brushes">
        /// An <see cref="Array"/> of <see cref="Brush"/> objects.</param>
        /// <param name="value">
        /// An <see cref="Int32"/> value indicating a <paramref name="brushes"/> element.</param>
        /// <param name="min">
        /// The lower limit for <paramref name="value"/>.</param>
        /// <param name="max">
        /// The upper limit for <paramref name="value"/>.</param>
        /// <returns><para>
        /// The <paramref name="brushes"/> element that corresponds to the specified <paramref
        /// name="value"/>, given a possible range from <paramref name="min"/> to <paramref
        /// name="max"/>.
        /// </para><para>-or-</para><para>
        /// A null reference if <paramref name="max"/> is less than or equal to <paramref
        /// name="min"/>.</para></returns>
        /// <exception cref="ArgumentNullOrEmptyException">
        /// <paramref name="brushes"/> is a null reference or an empty <see cref="Array"/>.
        /// </exception>
        /// <remarks><para>
        /// <b>GetBrush</b> converts the specified <paramref name="value"/>, ranging from <paramref
        /// name="min"/> to <paramref name="max"/>, to an index within the specified <paramref
        /// name="brushes"/>, ranging from zero to <see cref="Array.Length"/> minus one, and returns
        /// the <paramref name="brushes"/> element with that index.
        /// </para><para>
        /// <b>GetBrush</b> returns the first element if the specified <paramref name="value"/> is
        /// less than <paramref name="min"/>, and the last element if <paramref name="value"/> is
        /// greater than <paramref name="max"/>.</para></remarks>

        public static Brush GetBrush(Brush[] brushes, int value, int min, int max)
        {
            if (brushes == null || brushes.Length == 0)
            {
                ThrowHelper.ThrowArgumentNullOrEmptyException("brushes");
            }

            // check for invalid range
            int range = max - min;

            if (range <= 0)
            {
                return(null);
            }
            int maxBrush = brushes.Length - 1;

            // handle edge cases and invalid indices
            if (value >= max)
            {
                return(brushes[maxBrush]);
            }
            if (value <= min)
            {
                return(brushes[0]);
            }

            double index = maxBrush * (double)(value - min) / (double)range;

            return(brushes[Fortran.NInt(index)]);
        }
Esempio n. 7
0
    public IEnumerator GetAmberEGH(bool suppressStretches = false, bool suppressBends = false, bool suppressTorsions = true, bool suppressNonBonding = false)
    {
        _busy++;

        rmsForces = 0f;
        int c;

        for (int atomNum = 0; atomNum < atoms.size; atomNum++)
        {
            for (c = 0; c < 3; c++)
            {
                positions[atomNum * 3 + c] = atoms[atomNum].p[c];
            }
        }
        int numAtoms = size;

        forces = new double[numAtoms * 3];
        Fortran.allocate_atom_arrays(ref numAtoms);

        int status = 0;

        double[] stretchesEnergy = new double[2];
        double[] bendsEnergy     = new double[2];
        double[] torsionsEnergy  = new double[2];
        double[] vdwsEnergy      = new double[2];
        double[] coulombicEnergy = new double[2];

        Fortran.e_amber(positions, forces,
                        stretchesEnergy, bendsEnergy, torsionsEnergy, vdwsEnergy,
                        coulombicEnergy, ref rmsForces, ref status
                        );
        Fortran.CheckStatus(status);

        //GetStretchesEGH();
        //yield return null;
        //GetBendsEGH();
        //yield return null;
        //GetTorsionEGH();
        ///yield return null;
        //GetNonBondingEGH();
        //yield return null;

        allStretchesEnergy = stretchesEnergy[0];
        allBendsEnergy     = bendsEnergy[0];
        allTorsionsEnergy  = torsionsEnergy[0];
        allVdwsEnergy      = vdwsEnergy[0];
        allCoulombicEnergy = coulombicEnergy[0];

        amberEnergy = allStretchesEnergy + allBendsEnergy + allTorsionsEnergy + allVdwsEnergy + allCoulombicEnergy;
        totalEnergy = amberEnergy + kineticEnergy;
        for (int atomNum = 0; atomNum < atoms.size; atomNum++)
        {
            for (c = 0; c < 3; c++)
            {
                atoms[atomNum].force[c] = (float)forces[3 * atomNum + c];
            }
        }
        _busy--;
        yield return(null);
    }
Esempio n. 8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ChangeOverlay"/> class with the specified
        /// <see cref="OverlayImage"/>.</summary>
        /// <param name="editing">
        /// <c>true</c> to edit the <see cref="EditorOptions.Overlay"/> defined by the current <see
        /// cref="EditorOptions"/>; <c>false</c> to edit the <see cref="AreaSection.Overlay"/>
        /// defined by the current <see cref="AreaSection"/>.</param>
        /// <exception cref="InvalidOperationException">
        /// <paramref name="editing"/> is <c>true</c>, and <see cref="ApplicationInfo.IsEditor"/> is
        /// <c>false</c>.</exception>
        /// <remarks>
        /// The data of the specified <see cref="OverlayImage"/> may be changed in the dialog, as
        /// indicated by the value of the <see cref="DataChanged"/> property.</remarks>

        public ChangeOverlay(bool editing)
        {
            if (editing)
            {
                ApplicationInfo.CheckEditor();
                this._overlay = ApplicationOptions.Instance.Editor.Overlay;
            }
            else
            {
                this._overlay = MasterSection.Instance.Areas.Overlay;
            }

            // copy original data for user cancellation
            this._originalOverlay = (OverlayImage)this._overlay.Clone();
            this._editing         = editing;

            InitializeComponent();

            // set maximum ranges for image coordinates
            LeftUpDown.Minimum = Int32.MinValue;
            LeftUpDown.Maximum = Int32.MaxValue;
            TopUpDown.Minimum  = Int32.MinValue;
            TopUpDown.Maximum  = Int32.MaxValue;

            WidthUpDown.Minimum  = 1;
            WidthUpDown.Maximum  = Int32.MaxValue;
            HeightUpDown.Minimum = 1;
            HeightUpDown.Maximum = Int32.MaxValue;

            // show current map dimensions at 100% scale
            var mapBounds = MapViewManager.Instance.MapGrid.DisplayBounds;

            MapWidthInfo.Text  = mapBounds.Width.ToString("N0", ApplicationInfo.Culture);
            MapHeightInfo.Text = mapBounds.Height.ToString("N0", ApplicationInfo.Culture);

            BorderWidthInfo.Text  = MapView.MapBorder.X.ToString("N0", ApplicationInfo.Culture);
            BorderHeightInfo.Text = MapView.MapBorder.Y.ToString("N0", ApplicationInfo.Culture);

            // initialize size if at default values
            if (this._overlay.Bounds.Width == 1 && this._overlay.Bounds.Height == 1)
            {
                this._overlay.Bounds = new RectI(
                    this._overlay.Bounds.Left, this._overlay.Bounds.Top,
                    Fortran.NInt(mapBounds.Width), Fortran.NInt(mapBounds.Height));
            }

            // show current overlay data
            ShowImagePath();
            ShowImageSize();
            AspectToggle.IsChecked = this._overlay.PreserveAspectRatio;

            LeftUpDown.Value   = this._overlay.Bounds.Left;
            TopUpDown.Value    = this._overlay.Bounds.Top;
            WidthUpDown.Value  = this._overlay.Bounds.Width;
            HeightUpDown.Value = this._overlay.Bounds.Height;

            // construction completed
            this._initialized = true;
        }
Esempio n. 9
0
        /// <summary>
        /// Determines the index of the edge or vertex opposite to the edge or vertex with the
        /// specified index.</summary>
        /// <param name="index">
        /// The zero-based index of an edge or vertex. This value is taken <see
        /// cref="Fortran.Modulo"/> the current <see cref="Connectivity"/>, and may therefore be
        /// negative or greater than the maximum index.</param>
        /// <returns>
        /// The zero-based index of the edge or vertex opposite to the specified <paramref
        /// name="index"/>. This value is always less than <see cref="Connectivity"/>.</returns>
        /// <exception cref="PropertyValueException">
        /// <see cref="Connectivity"/> is not divisible by two. Opposing indices only exist if the
        /// total number of indices is even.</exception>
        /// <remarks>
        /// <b>OpposingIndex</b> should use the same index sequence as the <see
        /// cref="AngleToIndex"/> and <see cref="IndexToAngle"/> methods.</remarks>

        public int OpposingIndex(int index)
        {
            if (Connectivity % 2 != 0)
            {
                ThrowHelper.ThrowPropertyValueExceptionWithFormat(
                    "Connectivity", Connectivity, Strings.PropertyNotDivisible, 2);
            }

            return(Fortran.Modulo(index + Connectivity / 2, Connectivity));
        }
Esempio n. 10
0
        private void OnSave(object sender, RoutedEventArgs args)
        {
            args.Handled = true;

            // show preview and wait for input
            SaveGridDialog dialog = new SaveGridDialog()
            {
                Owner = this
            };

            dialog.VisualHost.VisualChild = CreateVisual(new PointD());
            if (dialog.ShowDialog() != true)
            {
                return;
            }

            // ask user for PNG file name
            string file = GetSaveFile();

            if (String.IsNullOrEmpty(file))
            {
                return;
            }

            // grow by (1,1) to ensure all lines are fully visible
            SizeD size   = Grid.DisplayBounds.Size;
            int   width  = Fortran.Ceiling(size.Width + 1),
                  height = Fortran.Ceiling(size.Height + 1);

            // render grid to standard ARGB bitmap
            RenderTargetBitmap bitmap = new RenderTargetBitmap(
                width, height, 96, 96, PixelFormats.Pbgra32);

            bitmap.Render(CreateVisual(new PointD()));
            bitmap.Freeze();

            try {
                // encode bitmap as PNG file
                PngBitmapEncoder encoder = new PngBitmapEncoder();
                encoder.Interlace = PngInterlaceOption.Off;
                encoder.Frames.Add(BitmapFrame.Create(bitmap));

                using (FileStream stream = new FileStream(file, FileMode.Create))
                    encoder.Save(stream);
            }
            catch (Exception e) {
                string message = String.Format(
                    "An error occurred while attempting\n" +
                    "to save the generated bitmap.\n\n{0}",
                    e.Message);

                MessageBox.Show(this, message, "Save Grid Error",
                                MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Converts the specified central angle to the index of the corresponding edge or vertex.
        /// </summary>
        /// <param name="angle">
        /// The central angle to convert, in degrees. This value is taken <see
        /// cref="Fortran.Modulo"/> 360 degrees, and may therefore be outside the interval [0, 360).
        /// </param>
        /// <returns>
        /// The zero-based index of the edge or vertex at the specified <paramref name="angle"/>.
        /// </returns>
        /// <remarks><para>
        /// The specified <paramref name="angle"/> is measured from the center of the <see
        /// cref="RegularPolygon"/>, and increases clockwise from the right-hand side of the x-axis.
        /// </para><para>
        /// If <see cref="VertexNeighbors"/> is <c>false</c>, the returned index enumerates all
        /// edges in clockwise direction. Counting starts at the topmost edge if <see
        /// cref="HasTopIndex"/> is <c>true</c>, and with the edge to the right of the topmost
        /// vertex otherwise.
        /// </para><para>
        /// If <see cref="VertexNeighbors"/> is <c>true</c>, the returned index enumerates all edges
        /// and vertices in an alternating sequence. Counting starts with the topmost edge for <see
        /// cref="PolygonOrientation.OnEdge"/> orientation and with the topmost vertex otherwise,
        /// continuing clockwise.
        /// </para><para>
        /// Valid indices range from zero to <see cref="Connectivity"/> less one. The 360 degrees of
        /// a full rotation around the central point are evenly divided among this range so that
        /// each index corresponds to an equal arc. If <see cref="VertexNeighbors"/> is <c>true</c>,
        /// the arcs that are mapped to edge indices cover only the central half of each edge. The
        /// arcs covering the outer parts are mapped to vertex indices instead.</para></remarks>

        public int AngleToIndex(double angle)
        {
            double segment = 360.0 / Connectivity;

            if (HasTopIndex)
            {
                angle += segment / 2.0;
            }
            angle = Fortran.Modulo(angle + 90.0, 360.0);
            return((int)(angle / segment));
        }
Esempio n. 12
0
        /// <summary>
        /// Converts the specified index of an edge or vertex to the corresponding central angle.
        /// </summary>
        /// <param name="index">
        /// The zero-based index of an edge or vertex. This value is taken <see
        /// cref="Fortran.Modulo"/> the current <see cref="Connectivity"/>, and may therefore be
        /// negative or greater than the maximum index.</param>
        /// <returns>
        /// The central angle, in degrees, of the edge or vertex with the specified <paramref
        /// name="index"/>. This value is always in the interval [0, 360).</returns>
        /// <remarks><para>
        /// If <see cref="VertexNeighbors"/> is <c>false</c>, the specified <paramref name="index"/>
        /// enumerates all edges in clockwise direction. Counting starts at the topmost edge if <see
        /// cref="HasTopIndex"/> is <c>true</c>, and with the edge to the right of the topmost
        /// vertex otherwise.
        /// </para><para>
        /// If <see cref="VertexNeighbors"/> is <c>true</c>, the specified <paramref name="index"/>
        /// enumerates all edges and vertices in an alternating sequence. Counting starts with the
        /// topmost edge for <see cref="PolygonOrientation.OnEdge"/> orientation and with the
        /// topmost vertex otherwise, continuing clockwise.
        /// </para><para>
        /// The returned angle is measured from the center of the <see cref="RegularPolygon"/>, and
        /// increases clockwise from the right-hand side of the x-axis.
        /// </para><para>
        /// Valid indices range from zero to <see cref="Connectivity"/> less one. The angle
        /// associated with each index is the angle from the central point to a vertex or to the
        /// middle of an edge, respectively.</para></remarks>

        public double IndexToAngle(int index)
        {
            double segment = 360.0 / Connectivity;
            double angle   = Fortran.Modulo(index, Connectivity) * segment;

            if (!HasTopIndex)
            {
                angle += segment / 2.0;
            }
            return(Fortran.Modulo(angle - 90.0, 360.0));
        }
Esempio n. 13
0
        /// <summary>
        /// Normalizes the specified angle, in degrees, to the interval [0, 360) after rounding to
        /// the nearest <see cref="Int32"/> number.</summary>
        /// <param name="degrees">
        /// The angle to normalize, in degrees.</param>
        /// <returns>
        /// The specified <paramref name="degrees"/> rounded to the nearest <see cref="Int32"/>
        /// number and normalized to the half-open interval [0, 360).</returns>
        /// <remarks>
        /// <b>NormalizeRoundedDegrees</b> uses <see cref="Fortran.NInt"/> to round the specified
        /// <paramref name="degrees"/> before normalization. The result is guaranteed to be an <see
        /// cref="Int32"/> value between 0 and 359.</remarks>

        public static int NormalizeRoundedDegrees(double degrees)
        {
            int angle = Fortran.NInt(degrees);

            angle %= 360;
            if (angle < 0)
            {
                angle += 360;
            }
            return(angle);
        }
Esempio n. 14
0
        /// <summary>
        /// Handles the <see cref="NumericUpDown.ValueChanged"/> event for the "Left", "Top",
        /// "Width", and "Height" <see cref="NumericUpDown"/> controls.</summary>
        /// <param name="sender">
        /// The <see cref="NumericUpDown"/> control sending the event.</param>
        /// <param name="args">
        /// An <see cref="EventArgs"/> object containing event data.</param>
        /// <remarks><para>
        /// <b>OnBoundsChanged</b> checks if the bounds specified by the "Coordinates" controls are
        /// actually different from the current <see cref="OverlayImage.Bounds"/> of the edited <see
        /// cref="OverlayImage"/>. (This may not be case for programmatic changes.)
        /// </para><para>
        /// If so, <b>OnBoundsChanged</b> updates the <see cref="OverlayImage"/> and the default
        /// <see cref="AreasTabContent.MapView"/> to reflect the new bounds, and sets the <see
        /// cref="DataChanged"/> flag.
        /// </para><para>
        /// If the "Preserve Original Aspect Ratio" option is enabled, <b>OnBoundsChanged</b> also
        /// adjusts the height of the <see cref="OverlayImage"/> if its width was changed, and vice
        /// versa, to preserve its original <see cref="OverlayImage.AspectRatio"/>.</para></remarks>

        private void OnBoundsChanged(object sender, EventArgs args)
        {
            if (this._ignoreEvents || !this._initialized)
            {
                return;
            }

            // retrieve bounds from numeric controls
            RectI bounds = new RectI(
                (int)LeftUpDown.Value, (int)TopUpDown.Value,
                (int)WidthUpDown.Value, (int)HeightUpDown.Value);

            // update overlay only if bounds have changed
            if (this._overlay.Bounds != bounds)
            {
                if (AspectToggle.IsChecked == true)
                {
                    bool widthChanged  = (sender == WidthUpDown.HostedControl);
                    bool heightChanged = (sender == HeightUpDown.HostedControl);

                    // adjust width or height to preserve aspect ratio
                    if (widthChanged || heightChanged)
                    {
                        double ratio = this._overlay.AspectRatio;
                        if (ratio > 0.0)
                        {
                            this._ignoreEvents = true;
                            int width = bounds.Width, height = bounds.Height;

                            if (widthChanged)
                            {
                                height             = Fortran.NInt(width / ratio);
                                HeightUpDown.Value = height;
                            }
                            else
                            {
                                Debug.Assert(heightChanged);
                                width             = Fortran.NInt(height * ratio);
                                WidthUpDown.Value = width;
                            }

                            bounds             = new RectI(bounds.Left, bounds.Top, width, height);
                            this._ignoreEvents = false;
                        }
                    }
                }

                // broadcast data changes
                this._overlay.Bounds = bounds;
                AreasTabContent.MapView.ShowOverlay(this, this._editing);
                DataChanged = true;
            }
        }
Esempio n. 15
0
        private PointI GetBitmapPosition(MouseEventArgs args)
        {
            // get rounded position relative to bitmap
            Point cursor = args.GetPosition(BitmapImage);
            int   x = Fortran.NInt(cursor.X), y = Fortran.NInt(cursor.Y);

            // check for valid position within bitmap
            if (x < 0 || y < 0 || x >= PaintBuffer.Size.Width || y >= PaintBuffer.Size.Height)
            {
                return(new PointI(-1, -1));
            }

            return(new PointI(x, y));
        }
Esempio n. 16
0
        /// <summary>
        /// Handles the <see cref="RangeBase.ValueChanged"/> event for the "Image" <see
        /// cref="ScrollBar"/>.</summary>
        /// <param name="sender">
        /// The <see cref="Object"/> where the event handler is attached.</param>
        /// <param name="args">
        /// A <see cref="RoutedPropertyChangedEventArgs{Double}"/> object containing event data.
        /// </param>
        /// <remarks>
        /// <b>OnFrameChanged</b> updates the "Image" group box with the selected image frame of the
        /// selected item in the "Entity Class" list view, if any.</remarks>

        private void OnFrameChanged(object sender, RoutedPropertyChangedEventArgs <Double> args)
        {
            // retrieve selected entity class, if any
            EntityClass entityClass = EntityList.SelectedItem as EntityClass;

            if (entityClass == null)
            {
                return;
            }

            // show selected image frame for entity class
            int frame = Fortran.NInt(FrameScrollBar.Value);

            ShowFrame(entityClass, frame);
        }
Esempio n. 17
0
    IEnumerator GetBestView(string atomsName)
    {
        Atoms atoms;

        if (atomsDictionary.TryGetValue(atomsName, out atoms))
        {
            if (atoms == null)
            {
                Debug.LogErrorFormat("Could not focus on atoms ({0}) - object is null", atomsName);
            }
            else
            {
                int      c;
                int      size                = atoms.size;
                double   fov                 = activeCamera.fieldOfView * Mathf.Deg2Rad;
                double   fill_amount         = 0.9f;
                double   min_distance        = 10f;
                double[] positions           = new double[size * 3];
                double[] new_camera_position = new double[3];
                for (int atomNum = 0; atomNum < atoms.size; atomNum++)
                {
                    for (c = 0; c < 3; c++)
                    {
                        positions[atomNum * 3 + c] = atoms[atomNum].p[c];
                    }
                }
                Fortran.getBestCameraView(positions, ref size, new_camera_position, ref fov, ref fill_amount, ref min_distance);
                activeCamera.transform.position = new Vector3((float)new_camera_position[0], (float)new_camera_position[1], (float)new_camera_position[2]);
            }
        }
        else
        {
            Debug.LogErrorFormat("Atoms ({0}) are not in Atoms Dictionary", atomsName);
        }

        yield return(null);
    }
Esempio n. 18
0
        /// <summary>
        /// Ensures that the <see cref="PaintBuffer"/> covers the specified minimum size.</summary>
        /// <param name="required">
        /// The new minimum size, in device-independent pixels, for the <see cref="PaintBuffer"/>.
        /// </param>
        /// <returns>
        /// <c>true</c> if the <see cref="PaintBuffer"/> must be cleared by the caller; otherwise,
        /// <c>false</c>.</returns>
        /// <remarks>
        /// To avoid frequent buffer reallocations, <b>EnsureBufferSize</b> grows the <see
        /// cref="PaintBuffer"/> to cover twice its current area or to the specified <paramref
        /// name="required"/> size, whichever is bigger. However, <b>EnsureBufferSize</b> will not
        /// grow the <see cref="PaintBuffer"/> beyond the device-independent size of the current
        /// virtual screen, unless the <paramref name="required"/> size is greater.</remarks>

        private bool EnsureBufferSize(SizeI required)
        {
            int   width, height;
            SizeI estimate = required;

            if (PaintBuffer != null)
            {
                width  = PaintBuffer.PixelWidth;
                height = PaintBuffer.PixelHeight;

                // quit if existing buffer is large enough
                if (width >= required.Width && height >= required.Height)
                {
                    return(true);
                }

                // new estimate: double current buffer area
                estimate = new SizeD(width * 1.4, height * 1.4).Round();
            }

            // default to virtual screen size
            SizeI screen = new SizeI(
                Fortran.Ceiling(SystemParameters.VirtualScreenWidth),
                Fortran.Ceiling(SystemParameters.VirtualScreenHeight));

            SizeI minimum = new SizeI(
                Math.Min(screen.Width, estimate.Width),
                Math.Min(screen.Height, estimate.Height));

            // choose maximum of screen size or required size
            width  = Math.Max(minimum.Width, required.Width);
            height = Math.Max(minimum.Height, required.Height);

            // reallocate buffer with new size
            PaintBuffer = new WriteableBitmap(width, height, 96, 96, PixelFormats.Pbgra32, null);
            return(false);
        }
Esempio n. 19
0
        /// <summary>
        /// Creates a <see cref="PointI"/> from the specified polar coordinates.</summary>
        /// <param name="length">
        /// The distance from the origin to the <see cref="PointI"/>.</param>
        /// <param name="angle">
        /// The polar angle, in radians, of the <see cref="PointI"/>.</param>
        /// <returns>
        /// A <see cref="PointI"/> whose <see cref="Length"/> and <see cref="Angle"/> equal the
        /// specified <paramref name="length"/> and <paramref name="angle"/>.</returns>
        /// <remarks><para>
        /// <b>FromPolar</b> returns <see cref="Empty"/> if the specified <paramref name="length"/>
        /// equals zero, and inverts the signs of the <see cref="X"/> and <see cref="Y"/>
        /// coordinates if <paramref name="length"/> is less than zero.
        /// </para><para>
        /// The calculated <see cref="X"/> and <see cref="Y"/> coordinates are converted to the
        /// nearest <see cref="Int32"/> values using <see cref="Fortran.NInt"/> rounding. The
        /// resulting <see cref="Length"/> and <see cref="Angle"/> may differ accordingly from the
        /// specified <paramref name="length"/> and <paramref name="angle"/>.</para></remarks>

        public static PointI FromPolar(double length, double angle)
        {
            return(new PointI(
                       Fortran.NInt(length * Math.Cos(angle)),
                       Fortran.NInt(length * Math.Sin(angle))));
        }
Esempio n. 20
0
        /// <summary>
        /// Converts the <see cref="LineD"/> to a <see cref="LineI"/> by rounding coordinates to the
        /// nearest <see cref="Int32"/> values.</summary>
        /// <returns>
        /// A <see cref="LineI"/> instance whose <see cref="LineI.Start"/> and <see
        /// cref="LineI.End"/> properties equal the corresponding properties of the <see
        /// cref="LineD"/>, rounded to the nearest <see cref="Int32"/> values.</returns>
        /// <remarks>
        /// The <see cref="Double"/> coordinates of the <see cref="LineD"/> are converted to <see
        /// cref="Int32"/> coordinates using <see cref="Fortran.NInt"/> rounding.</remarks>

        public LineI Round()
        {
            return(new LineI(
                       Fortran.NInt(Start.X), Fortran.NInt(Start.Y),
                       Fortran.NInt(End.X), Fortran.NInt(End.Y)));
        }
Esempio n. 21
0
        /// <summary>
        /// Draws the specified image frame to the specified <see cref="WriteableBitmap"/>.
        /// </summary>
        /// <param name="targetBitmap">
        /// The <see cref="WriteableBitmap"/> for the drawing.</param>
        /// <param name="target">
        /// The region within <paramref name="targetBitmap"/> on which the copied image frame is
        /// centered.</param>
        /// <param name="frameBitmap">
        /// A <see cref="WriteableBitmap"/> containing exactly the image frame to copy.</param>
        /// <param name="scalingX">
        /// An <see cref="ImageScaling"/> value indicating the horizontal scaling of the <paramref
        /// name="frameBitmap"/> to fit the specified <paramref name="target"/> region.</param>
        /// <param name="scalingY">
        /// An <see cref="ImageScaling"/> value indicating the vertical scaling of the <paramref
        /// name="frameBitmap"/> fit the specified <paramref name="target"/> region.</param>
        /// <param name="offset">
        /// An optional pixel offset that is added to the centered location within the <paramref
        /// name="target"/> region.</param>
        /// <param name="scalingVector">
        /// An optional scaling vector whose negative components indicate the specified <paramref
        /// name="frameBitmap"/> should be mirrored along the corresponding axis. Specify zero or
        /// positive components for no mirroring.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="targetBitmap"/> or <paramref name="frameBitmap"/> is a null reference.
        /// </exception>
        /// <exception cref="InvalidEnumArgumentException">
        /// <paramref name="scalingX"/> or <paramref name="scalingY"/> equals <see
        /// cref="ImageScaling.Stretch"/>.</exception>
        /// <remarks>
        /// <b>DrawFrameCore</b> is called by <see cref="DrawFrame"/> when drawing to a <see
        /// cref="WriteableBitmap"/> without <see cref="ImageScaling.Stretch"/> scaling.</remarks>

        private static void DrawFrameCore(WriteableBitmap targetBitmap, RectI target,
                                          WriteableBitmap frameBitmap, ImageScaling scalingX, ImageScaling scalingY,
                                          PointI offset, PointI scalingVector)
        {
            if (targetBitmap == null)
            {
                ThrowHelper.ThrowArgumentNullException("targetBitmap");
            }
            if (frameBitmap == null)
            {
                ThrowHelper.ThrowArgumentNullException("frameBitmap");
            }

            // compute coordinates of centered & offset frame
            SizeI source = new SizeI(frameBitmap.PixelWidth, frameBitmap.PixelHeight);
            int   x = Fortran.NInt(target.X + offset.X + (target.Width - source.Width) / 2.0);
            int   y = Fortran.NInt(target.Y + offset.Y + (target.Height - source.Height) / 2.0);
            int   endX = x + source.Width, endY = y + source.Height;

            // adjust horizontal coordinates for desired scaling
            switch (scalingX)
            {
            case ImageScaling.Repeat:
                while (x > target.X)
                {
                    x -= source.Width;
                }
                endX = target.Right;
                break;

            case ImageScaling.Stretch:
                ThrowHelper.ThrowInvalidEnumArgumentException(
                    "scalingX", (int)scalingX, typeof(ImageScaling));
                break;
            }

            // adjust vertical coordinates for desired scaling
            switch (scalingY)
            {
            case ImageScaling.Repeat:
                while (y > target.Y)
                {
                    y -= source.Height;
                }
                endY = target.Bottom;
                break;

            case ImageScaling.Stretch:
                ThrowHelper.ThrowInvalidEnumArgumentException(
                    "scalingY", (int)scalingY, typeof(ImageScaling));
                break;
            }

            // check scaling vector for mirroring
            bool mirrorX = (scalingVector.X < 0);
            bool mirrorY = (scalingVector.Y < 0);

            // repeatedly copy frame to fill target bounds
            for (int dx = x; dx < endX; dx += source.Width)
            {
                for (int dy = y; dy < endY; dy += source.Height)
                {
                    // adjust for obscured upper & left edges
                    int sourceX = 0, sourceY = 0, targetX = 0, targetY = 0;
                    if (dx < 0)
                    {
                        sourceX = -dx;
                    }
                    else
                    {
                        targetX = dx;
                    }
                    if (dy < 0)
                    {
                        sourceY = -dy;
                    }
                    else
                    {
                        targetY = dy;
                    }

                    // adjust for obscured lower & right edges
                    int width  = Math.Min(source.Width - sourceX, target.Right - targetX);
                    int height = Math.Min(source.Height - sourceY, target.Bottom - targetY);
                    if (width <= 0 || height <= 0)
                    {
                        continue;
                    }

                    // call mirroring overload only if necessary
                    RectI bounds = new RectI(sourceX, sourceY, width, height);
                    if (mirrorX || mirrorY)
                    {
                        targetBitmap.Read(targetX, targetY, frameBitmap, bounds, mirrorX, mirrorY);
                    }
                    else
                    {
                        targetBitmap.Read(targetX, targetY, frameBitmap, bounds);
                    }
                }
            }
        }
Esempio n. 22
0
        /// <summary>
        /// Renders the visual content of the <see cref="MapViewRenderer"/>.</summary>
        /// <param name="context">
        /// The <see cref="DrawingContext"/> for the rendering.</param>
        /// <remarks><para>
        /// <b>OnRender</b> calls the base class implementation of <see cref="UIElement.OnRender"/>,
        /// and then immediately returns if the associated <see cref="MapView"/> has not been fully
        /// initialized yet, or already been disposed of.
        /// </para><para>
        /// Otherwise, <b>OnRender</b> redraws the current <see cref="MapViewControl.Viewport"/>.
        /// The <see cref="Graphics.MapView.Extent"/> of the associated <see cref="MapView"/>
        /// outside the current <see cref="MapViewControl.Viewport"/> remains empty.
        /// </para></remarks>

        protected override void OnRender(DrawingContext context)
        {
            base.OnRender(context);
            if (MapView.Catalog == null || MapView.IsDisposed)
            {
                return;
            }

            // check if there is anything to render
            Rect viewRegion = Control.Viewport;

            if (viewRegion.Width == 0 || viewRegion.Height == 0)
            {
                return;
            }

            // distance from center point to upper-left corner
            double centerX = MapView.TileWidth / 2.0;
            double centerY = MapView.TileHeight / 2.0;

            // compute sites covered by viewport
            RectD region     = viewRegion.ToRectD();
            RectI intRegion  = region.Circumscribe();
            RectI siteRegion = MapView.ViewToSite(region);

            // resize & clear paint buffer
            bool mustClear = EnsureBufferSize(intRegion.Size);

            PaintBuffer.Lock();
            if (mustClear)
            {
                PaintBuffer.Clear();
            }

            // cache performance options
            this._bitmapGrid   = ApplicationOptions.Instance.View.BitmapGrid;
            this._opaqueImages = ApplicationOptions.Instance.View.OpaqueImages;

            // draw entities of all sites within region
            for (int x = siteRegion.Left; x < siteRegion.Right; x++)
            {
                for (int y = siteRegion.Top; y < siteRegion.Bottom; y++)
                {
                    Site site = MapView.WorldState.Sites[x, y];

                    // compute upper-left corner of bitmap tile
                    PointD display = MapView.SiteToView(site.Location);
                    PointI pixel   = new PointI(
                        Fortran.NInt(display.X - centerX),
                        Fortran.NInt(display.Y - centerY));

                    // draw entities in current site
                    DrawEntities(pixel, intRegion, site);
                }
            }

            // copy paint buffer to viewport
            PaintBuffer.Unlock();
            context.DrawImage(PaintBuffer,
                              new Rect(region.Left, region.Top, PaintBuffer.Width, PaintBuffer.Height));

            // draw optional decoration on all sites
            DrawDecoration(context, siteRegion);
        }
Esempio n. 23
0
        /// <summary>
        /// Converts the <see cref="PointF"/> to a <see cref="PointI"/> by rounding coordinates to
        /// the nearest <see cref="Int32"/> values.</summary>
        /// <returns>
        /// A <see cref="PointI"/> instance whose <see cref="PointI.X"/> and <see cref="PointI.Y"/>
        /// properties equal the corresponding properties of the <see cref="PointF"/>, rounded to
        /// the nearest <see cref="Int32"/> values.</returns>
        /// <remarks>
        /// The <see cref="Single"/> coordinates of the <see cref="PointF"/> are converted to <see
        /// cref="Int32"/> coordinates using <see cref="Fortran.NInt"/> rounding.</remarks>

        public PointI Round()
        {
            return(new PointI(Fortran.NInt(X), Fortran.NInt(Y)));
        }
Esempio n. 24
0
    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Q))
        {
            Fortran.deallocate_all();
            main.ClearQueue();
                         #if UNITY_EDITOR
            UnityEditor.EditorApplication.isPlaying = false;
                        #else
            Application.Quit();
                        #endif
        }

        //Handle key presses
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            if (activeAtoms)
            {
                activeAtoms.ClearSelection();
            }
        }

        //Keep track of mouse position here
        screenMousePosition = Input.mousePosition;
        worldMousePosition  = activeCamera.ScreenToWorldPoint(new Vector3(screenMousePosition.x, screenMousePosition.y, activeCamera.nearClipPlane));

        leftClickDown  = Input.GetAxis("Left Click");
        rightClickDown = Input.GetAxis("Right Click");

        //Handle 6-axis motion
        mouseX = Input.GetAxis("Mouse X");
        mouseY = Input.GetAxis("Mouse Y");

        rotation.x = leftClickDown * mouseY;
        rotation.y = leftClickDown * mouseX;
        rotation.z = rightClickDown * mouseX;

        activeCamera.transform.localPosition += Input.GetAxis("Pan") * activeCamera.transform.right + Input.GetAxis("Vertical") * activeCamera.transform.up + Input.GetAxis("Forward") * activeCamera.transform.forward;
        activeCamera.transform.Rotate(rotation);

        //Differentiate between click and drag
        clicked = false;
        if (leftClickDown == 0)
        {
            clicked = (oldLeftClickDown != 0 && !dragged);
            dragged = false;
        }
        else
        {
            if (!dragged)
            {
                dragged = (mouseX * mouseX + mouseY * mouseY > dragThreshold);
            }
        }
        oldLeftClickDown = leftClickDown;

        //Get hovered atom
        if (activeAtoms != null)
        {
            frameNum++;
            if (frameNum == framesUntilRefresh)
            {
                frameNum = 0;
            }
            else
            {
                ray = activeCamera.ScreenPointToRay(screenMousePosition);

                //MOVE ALL HOVER HALOES TO ATOMS

                RaycastHit[] hitInfos;
                hitInfos = Physics.RaycastAll(ray);
                numHits  = hitInfos.Length;

                if (numHits > 0)
                {
                    closestAtom = null;
                    hitAtom     = null;

                    closestAngle = 90f;

                    for (int i = 0; i < numHits; i++)
                    {
                        hitInfo       = hitInfos [i];
                        mouseCollider = hitInfo.collider.gameObject.GetComponent <MouseCollider> ();

                        if (mouseCollider == null)
                        {
                            continue;
                        }

                        hitAtom = mouseCollider.parent;

                        if (hitAtom.parent != activeAtoms)
                        {
                            continue;
                        }

                        //Make sure the atom that's closest to the cursor is selected
                        angle = Vector3.Angle(ray.direction, hitAtom.transform.position - activeCamera.transform.position);
                        if (angle > closestAngle)
                        {
                            continue;
                        }

                        closestAtom      = hitAtom;
                        closestAtomIndex = hitAtom.index;
                        closestAngle     = angle;
                    }

                    if (closestAtom != null)
                    {
                        if (closestAtomIndex != activeAtoms.hoveredAtom)
                        {
                            activeAtoms.hoveredAtom = closestAtomIndex;
                        }

                        if (clicked)
                        {
                            activeAtoms.ToggleSelect(closestAtomIndex);
                        }
                    }
                }
                else
                {
                    if (hitAtom != null)
                    {
                        activeAtoms.hoveredAtom = -1;
                    }
                }
            }
        }
        //if (Physics.Raycast (ray, out hitInfo)) {
        //	MouseCollider hoveredAtomCollider = hitInfo.collider.gameObject.GetComponent<MouseCollider> ();
        //
        //	if (hoveredAtomCollider != null) {
        //		hoveredAtomCollider.parent.parent.hoveredAtom = hoveredAtomCollider.parent.index;
        //	}
        //}
    }
Esempio n. 25
0
    public IEnumerator AMBEROpt(int steps, int updateAfterSteps = 5)
    {
        _busy++;

        int status   = 0;
        int c        = 0;
        int numAtoms = size;

        positions = new double[numAtoms * 3];

        for (int atomNum = 0; atomNum < numAtoms; atomNum++)
        {
            for (c = 0; c < 3; c++)
            {
                positions[3 * atomNum + c] = atoms[atomNum].p[c];
            }
        }

        Fortran.allocate_atom_arrays(ref numAtoms);

        IEnumerator iEnumerator;

        iEnumerator = InitialiseParameters();
        while (iEnumerator.MoveNext())
        {
        }
        yield return(null);

        double[] stretchesEnergy = new double[2];
        double[] bendsEnergy     = new double[2];
        double[] torsionsEnergy  = new double[2];
        double[] vdwsEnergy      = new double[2];
        double[] coulombicEnergy = new double[2];

        string logPath = "/Users/tristanmackenzie/Unity/ONIOM/Assets/Plugins/out.log";

        System.IO.File.Delete(logPath);

        double convergence_threshold = 0.00001;
        int    precision             = 3;
        int    iprint             = 0;
        int    matrix_corrections = 17;

        int     stepNum   = 0;
        Vector3 vPosition = new Vector3();

        while (stepNum < steps)
        {
            writeArray(positions, logPath);
            Fortran.lbfgs_optimise(positions, ref updateAfterSteps,
                                   stretchesEnergy, bendsEnergy, torsionsEnergy,
                                   vdwsEnergy, coulombicEnergy, ref convergence_threshold,
                                   ref precision, ref iprint, ref matrix_corrections, ref status
                                   );
            writeArray(positions, logPath);
            Fortran.CheckStatus(status);

            allStretchesEnergy = stretchesEnergy[0];
            allBendsEnergy     = bendsEnergy[0];
            allTorsionsEnergy  = torsionsEnergy[0];
            allVdwsEnergy      = vdwsEnergy[0];
            allCoulombicEnergy = coulombicEnergy[0];

            amberEnergy = allStretchesEnergy + allBendsEnergy + allTorsionsEnergy + allVdwsEnergy + allCoulombicEnergy;
            totalEnergy = amberEnergy + kineticEnergy;

            stepNum += updateAfterSteps;
            for (int atomNum = 0; atomNum < numAtoms; atomNum++)
            {
                for (c = 0; c < 3; c++)
                {
                    vPosition[c] = (float)positions[3 * atomNum + c];
                }
                atoms[atomNum].transform.localPosition = vPosition;
            }

            yield return(null);
        }

        _busy--;
        yield return(null);
    }
Esempio n. 26
0
    public IEnumerator MDVerlet(int steps, int updateAfterSteps = 5)
    {
        _busy++;

        int status   = 0;
        int c        = 0;
        int numAtoms = size;

        positions = new double[numAtoms * 3];

        for (int atomNum = 0; atomNum < numAtoms; atomNum++)
        {
            for (c = 0; c < 3; c++)
            {
                positions[3 * atomNum + c] = atoms[atomNum].p[c];
            }
        }



        Fortran.allocate_atom_arrays(ref numAtoms);

        IEnumerator iEnumerator;

        iEnumerator = InitialiseParameters();
        while (iEnumerator.MoveNext())
        {
        }
        yield return(null);

        double[] stretchesEnergy = new double[2];
        double[] bendsEnergy     = new double[2];
        double[] torsionsEnergy  = new double[2];
        double[] vdwsEnergy      = new double[2];
        double[] coulombicEnergy = new double[2];

        double mdTimeStep      = atoms.globalSettings.mdTimeStep;
        double mdDampingFactor = atoms.globalSettings.mdDampingFactor;

        string logPath = "/Users/tristanmackenzie/Unity/ONIOM/Assets/Plugins/out.log";

        System.IO.File.Delete(logPath);

        //Run MD
        int     stepNum   = 0;
        Vector3 vPosition = new Vector3();

        while (stepNum < steps)
        {
            writeArray(positions, logPath);
            Fortran.md_verlet(positions, ref updateAfterSteps,
                              ref mdTimeStep, ref mdDampingFactor,
                              stretchesEnergy, bendsEnergy, torsionsEnergy, vdwsEnergy, coulombicEnergy,
                              ref kineticEnergy, ref rmsForces, ref status);
            writeArray(positions, logPath);
            Fortran.CheckStatus(status);

            allStretchesEnergy = stretchesEnergy[0];
            allBendsEnergy     = bendsEnergy[0];
            allTorsionsEnergy  = torsionsEnergy[0];
            allVdwsEnergy      = vdwsEnergy[0];
            allCoulombicEnergy = coulombicEnergy[0];

            amberEnergy = allStretchesEnergy + allBendsEnergy + allTorsionsEnergy + allVdwsEnergy + allCoulombicEnergy;
            totalEnergy = amberEnergy + kineticEnergy;

            stepNum += updateAfterSteps;
            for (int atomNum = 0; atomNum < numAtoms; atomNum++)
            {
                for (c = 0; c < 3; c++)
                {
                    vPosition[c] = (float)positions[3 * atomNum + c];
                }
                atoms[atomNum].transform.localPosition = vPosition;
            }

            yield return(null);
        }

        _busy--;
        yield return(null);
    }
Esempio n. 27
0
            /// <summary>
            /// Draws a set of line graphs connecting the specified point collections to the
            /// specified <see cref="DrawingContext"/>.</summary>
            /// <param name="context">
            /// The <see cref="DrawingContext"/> for the rendering.</param>
            /// <param name="bounds">
            /// The region within <paramref name="context"/>, in device-independent pixels, where to
            /// draw.</param>
            /// <param name="colors">
            /// An <see cref="Array"/> containing the <see cref="Color"/> for each graph.</param>
            /// <param name="points">
            /// An <see cref="Array"/> containing the <see cref="Point"/> collections that
            /// constitute each graph.</param>
            /// <param name="typeface">
            /// The <see cref="Typeface"/> to use for axis labels.</param>
            /// <exception cref="ArgumentException">
            /// <paramref name="colors"/> and <paramref name="points"/> contain a different number
            /// of elements.</exception>
            /// <exception cref="ArgumentNullException">
            /// <paramref name="context"/>, <paramref name="colors"/>, <paramref name="points"/>, or
            /// <paramref name="typeface"/> is a null reference.</exception>
            /// <remarks>
            /// <b>DrawGraph</b> does nothing if the specified <paramref name="points"/> array is
            /// empty, or contains only empty <see cref="Point"/> collections.</remarks>

            private static void DrawGraph(DrawingContext context, Rect bounds,
                                          Color[] colors, Point[][] points, Typeface typeface)
            {
                if (context == null)
                {
                    ThrowHelper.ThrowArgumentNullException("context");
                }
                if (colors == null)
                {
                    ThrowHelper.ThrowArgumentNullException("colors");
                }
                if (points == null)
                {
                    ThrowHelper.ThrowArgumentNullException("values");
                }
                if (typeface == null)
                {
                    ThrowHelper.ThrowArgumentNullException("typeface");
                }

                if (colors.Length != points.Length)
                {
                    ThrowHelper.ThrowArgumentExceptionWithFormat(
                        "colors", Tektosyne.Strings.ArgumentConflict, "points");
                }

                // check for empty drawing region
                if (bounds.Width <= 0 || bounds.Height <= 0)
                {
                    return;
                }

                Point minimum = new Point(Double.MaxValue, Double.MaxValue);
                Point maximum = new Point(Double.MinValue, Double.MinValue);

                // determine minimum and maximum coordinates
                foreach (Point[] line in points)
                {
                    if (line == null)
                    {
                        continue;
                    }

                    foreach (Point point in line)
                    {
                        if (minimum.X > point.X)
                        {
                            minimum.X = point.X;
                        }
                        if (maximum.X < point.X)
                        {
                            maximum.X = point.X;
                        }

                        if (minimum.Y > point.Y)
                        {
                            minimum.Y = point.Y;
                        }
                        if (maximum.Y < point.Y)
                        {
                            maximum.Y = point.Y;
                        }
                    }
                }

                // check for empty point collections
                if (minimum.X > maximum.X || minimum.Y > maximum.Y)
                {
                    return;
                }

                // ensure non-empty ranges along both axes
                if (minimum.X == maximum.X)
                {
                    ++maximum.X;
                }
                if (minimum.Y == maximum.Y)
                {
                    --minimum.Y; ++maximum.Y;
                }

                // determine horizontal and vertical scale
                double scaleX = bounds.Width / (maximum.X - minimum.X);
                double scaleY = bounds.Height / (maximum.Y - minimum.Y);

                // determine horizontal and vertical origin
                Point origin = new Point(
                    bounds.Left - scaleX * minimum.X,
                    bounds.Top + scaleY * maximum.Y);

                // create required pens
                Pen blackPen = new Pen(Brushes.Black, 1.0);
                Pen lightPen = new Pen(Brushes.LightGray, 1.0);

                // draw black lines of origin
                context.DrawLine(blackPen,
                                 new Point(origin.X, bounds.Top), new Point(origin.X, bounds.Bottom));
                context.DrawLine(blackPen,
                                 new Point(bounds.Left, origin.Y), new Point(bounds.Right, origin.Y));

                // calculate optimal axis divisions
                Point division = new Point(
                    GetAxisDivision(maximum.X - minimum.X),
                    GetAxisDivision(maximum.Y - minimum.Y));

                // draw vertical tick lines and labels
                for (double tick = (maximum.X / division.X) * division.X;
                     tick >= minimum.X; tick -= division.X)
                {
                    // draw division line
                    double x = origin.X + tick * scaleX;
                    context.DrawLine(lightPen, new Point(x, bounds.Top), new Point(x, bounds.Bottom));

                    // print label left of line
                    string tickText = tick.ToString("N0", ApplicationInfo.Culture);
                    var    text     = new FormattedText(tickText, ApplicationInfo.Culture,
                                                        FlowDirection.LeftToRight, typeface, 10, Brushes.Black);

                    context.DrawText(text, new Point(x - 12, bounds.Top + 2));
                }

                // draw horizontal tick lines and labels
                for (double tick = (maximum.Y / division.Y) * division.Y;
                     tick >= minimum.Y; tick -= division.Y)
                {
                    // draw division line
                    double y = origin.Y - Fortran.NInt(tick * scaleY);
                    context.DrawLine(lightPen, new Point(bounds.Left, y), new Point(bounds.Right, y));

                    // print label below line
                    string tickText = tick.ToString("N0", ApplicationInfo.Culture);
                    var    text     = new FormattedText(tickText, ApplicationInfo.Culture,
                                                        FlowDirection.LeftToRight, typeface, 10, Brushes.Black);

                    context.DrawText(text, new Point(bounds.Left + 4, y + 2));
                }

                // draw all point collections
                for (int i = 0; i < points.Length; i++)
                {
                    Point[] line = points[i];
                    if (line == null)
                    {
                        continue;
                    }

                    // draw lines from one point to the next
                    Pen pen = new Pen(new SolidColorBrush(colors[i]), 2.0);
                    for (int j = 0; j < line.Length - 1; j++)
                    {
                        Point p0 = new Point(origin.X + line[j].X * scaleX,
                                             origin.Y - line[j].Y * scaleY);

                        Point p1 = new Point(origin.X + line[j + 1].X * scaleX,
                                             origin.Y - line[j + 1].Y * scaleY);

                        context.DrawLine(pen, p0, p1);
                    }
                }
            }
Esempio n. 28
0
    public void InitialiseTorsions(bool suppress = true)
    {
        DihedralConnection dihedral;
        Torsion            torsion;

        DihedralConnection[] dihedrals = dihedralsDict.Values.ToArray();

        List <int>    torsionAtomNumList = new List <int>();
        List <double> torsionVList       = new List <double>();
        List <double> torsionGammaList   = new List <double>();
        List <double> torsionPathList    = new List <double>();
        int           numTorsions        = 0;
        double        npaths;

        for (int i = 0; i < dihedrals.Length; i++)
        {
            dihedral = dihedrals[i];
            torsion  = GetTorsionParameter(dihedral);
            if (torsion == null)
            {
                if (!suppress)
                {
                    throw new NoParameterException(typeof(Torsion), dihedral.atom0, dihedral.atom1, dihedral.atom2, dihedral.atom3);
                }
                continue;
            }

            torsionVList.Add(torsion.v0);
            torsionVList.Add(torsion.v1);
            torsionVList.Add(torsion.v2);
            torsionVList.Add(torsion.v3);
            torsionGammaList.Add(Mathf.Deg2Rad * torsion.gamma0);
            torsionGammaList.Add(Mathf.Deg2Rad * torsion.gamma1);
            torsionGammaList.Add(Mathf.Deg2Rad * torsion.gamma2);
            torsionGammaList.Add(Mathf.Deg2Rad * torsion.gamma3);

            if (torsion.npaths > 0.0)
            {
                npaths = torsion.npaths;
            }
            else
            {
                //Determine number of paths from connectivity
                npaths = (double)
                         (neighbourCount[dihedral.atom1.index] - 1) *
                         (neighbourCount[dihedral.atom2.index] - 1)
                ;
                if (npaths <= 0.0)
                {
                    throw new System.Exception(string.Format(
                                                   "Error defining torsion: Atom {0} has {1} neighbours. Atom {2} has {3} neighbours",
                                                   dihedral.atom1.index,
                                                   neighbourCount[dihedral.atom1.index],
                                                   dihedral.atom2.index,
                                                   neighbourCount[dihedral.atom2.index]
                                                   )
                                               );
                }
            }

            torsionPathList.Add(npaths);

            torsionAtomNumList.Add(dihedral.atom0.index);
            torsionAtomNumList.Add(dihedral.atom1.index);
            torsionAtomNumList.Add(dihedral.atom2.index);
            torsionAtomNumList.Add(dihedral.atom3.index);


            numTorsions++;
        }

        Fortran.set_torsions(
            ref numTorsions,
            torsionAtomNumList.ToArray(),
            torsionVList.ToArray(),
            torsionGammaList.ToArray(),
            torsionPathList.ToArray()
            );
    }
Esempio n. 29
0
        /// <summary>
        /// Converts the <see cref="SizeF"/> to a <see cref="SizeI"/> by rounding dimensions to the
        /// nearest <see cref="Int32"/> values.</summary>
        /// <returns>
        /// A <see cref="SizeI"/> instance whose <see cref="SizeI.Width"/> and <see
        /// cref="SizeI.Height"/> properties equal the corresponding properties of the <see
        /// cref="SizeF"/>, rounded to the nearest <see cref="Int32"/> values.</returns>
        /// <remarks>
        /// The <see cref="Single"/> dimensions of the <see cref="SizeF"/> are converted to <see
        /// cref="Int32"/> dimensions using <see cref="Fortran.NInt"/> rounding.</remarks>

        public SizeI Round()
        {
            return(new SizeI(Fortran.NInt(Width), Fortran.NInt(Height)));
        }
Esempio n. 30
0
    public void InitialiseNonBonding(bool suppress = false)
    {
        int a0;
        int a1;
        int bondDistance;

        double amberVCutoff = parameters.nonbonding.vCutoff == 0f ? atoms.globalSettings.maxNonBondingCutoff : parameters.nonbonding.vCutoff;
        double amberCCutoff = parameters.nonbonding.cCutoff == 0f ? atoms.globalSettings.maxNonBondingCutoff : parameters.nonbonding.cCutoff;

        float vScale;
        float cScale;

        float[] vScales = parameters.nonbonding.vScales;
        float[] cScales = parameters.nonbonding.cScales;

        Dictionary <string, VdW> vdwDict = new Dictionary <string, VdW>();

        foreach (VdW vdw in parameters.vdws)
        {
            vdwDict.Add(vdw.t, vdw);
        }

        VdW  vdw0;
        VdW  vdw1;
        Atom atom0;
        Atom atom1;

        int numNonBonding   = size * (size - 1) / 2;
        int nonBondingIndex = 0;

        double[] q0q1s              = new double[numNonBonding];
        double[] vdwREqs            = new double[numNonBonding];
        double[] vdwVs              = new double[numNonBonding];
        int[]    nonBondingAtomNums = new int[numNonBonding * 2];

        for (a0 = 0; a0 < size - 1; a0++)
        {
            atom0 = atoms[a0];

            if (!vdwDict.TryGetValue(atom0.amberName, out vdw0))
            {
                if (!suppress)
                {
                    throw new NoParameterException(typeof(VdW), atom0);
                }
                for (a1 = a0 + 1; a1 < size; a1++)
                {
                    nonBondingAtomNums[nonBondingIndex * 2]     = a0;
                    nonBondingAtomNums[nonBondingIndex * 2 + 1] = a1;
                    nonBondingIndex++;
                }
                continue;
            }

            for (a1 = a0 + 1; a1 < size; a1++)
            {
                atom1        = atoms[a1];
                bondDistance = distanceMatrix[a0, a1];

                vScale = vScales[bondDistance];
                cScale = cScales[bondDistance];

                nonBondingAtomNums[nonBondingIndex * 2]     = a0;
                nonBondingAtomNums[nonBondingIndex * 2 + 1] = a1;

                if (vScale != 0f)
                {
                    if (vdwDict.TryGetValue(atom1.amberName, out vdw1))
                    {
                        q0q1s[nonBondingIndex]   = cScale * atom0.partialCharge * atom0.partialCharge;
                        vdwREqs[nonBondingIndex] = (vdw0.r + vdw1.r) * 0.5f;
                        vdwVs[nonBondingIndex]   = Mathf.Sqrt(vdw0.v * vdw1.v) * vScale;
                    }
                    ;
                }
                else
                {
                }

                nonBondingIndex++;
            }
        }

        Fortran.set_non_bonding(
            ref numNonBonding,
            nonBondingAtomNums,
            vdwVs,
            vdwREqs,
            ref amberVCutoff,
            q0q1s,
            ref parameters.dielectricConstant,
            ref amberCCutoff
            );
    }