示例#1
0
 /// <summary>
 /// Constructs an empty, forward reaction.
 /// </summary>
 public Reaction()
 {
     this.reactants = Builder.NewAtomContainerSet();
     this.products  = Builder.NewAtomContainerSet();
     this.agents    = Builder.NewAtomContainerSet();
     this.mappings  = new List <IMapping>();
     direction      = ReactionDirection.Forward;
 }
示例#2
0
        public virtual void TestSetDirection_IReaction_Direction()
        {
            IReaction         reaction  = (IReaction)NewChemObject();
            ReactionDirection direction = ReactionDirection.Bidirectional;

            reaction.Direction = direction;
            Assert.AreEqual(direction, reaction.Direction);
        }
示例#3
0
        public ReactionDepiction(RendererModel model,
                                 List <Bounds> reactants,
                                 List <Bounds> products,
                                 List <Bounds> agents,
                                 Bounds plus,
                                 ReactionDirection direction,
                                 Dimensions dimensions,
                                 IList <Bounds> reactantTitles,
                                 IList <Bounds> productTitles,
                                 Bounds title,
                                 Bounds conditions,
                                 Color fgcol)
            : base(model)
        {
            this.model      = model;
            this.dimensions = dimensions;
            this.title      = title;
            this.fgcol      = fgcol;

            // side components (catalysts, solvents, etc) note we deliberately
            // swap sideGrid width and height as we to stack agents on top of
            // each other. By default determineGrid tries to make the grid
            // wide but we want it tall
            this.sideComps.AddRange(agents);
            var sideGrid      = Dimensions.DetermineGrid(sideComps.Count);
            var prelimSideDim = Dimensions.OfGrid(sideComps,
                                                  yOffsetSide = new double[sideGrid.Width + 1],
                                                  xOffsetSide = new double[sideGrid.Height + 1]);

            // build the main components, we add a 'plus' between each molecule
            foreach (var reactant in reactants)
            {
                this.mainComp.Add(reactant);
                this.mainComp.Add(plus);
            }

            // replacing trailing plus with placeholder for arrow
            if (!reactants.Any())
            {
                this.mainComp.Add(new Bounds());
            }
            else
            {
                this.mainComp[this.mainComp.Count - 1] = new Bounds();
            }

            foreach (var product in products)
            {
                this.mainComp.Add(product);
                this.mainComp.Add(plus);
            }

            // trailing plus not needed
            if (products.Any())
            {
                this.mainComp.RemoveAt(this.mainComp.Count - 1);
            }

            // add title if supplied, we simply line them up with
            // the main components and the add them as an extra
            // row
            if (reactantTitles.Any() || productTitles.Any())
            {
                if (reactantTitles.Any() && reactantTitles.Count != reactants.Count)
                {
                    throw new ArgumentException("Number of reactant titles differed from number of reactants");
                }
                if (productTitles.Any() && productTitles.Count != products.Count)
                {
                    throw new ArgumentException("Number of product titles differed from number of products");
                }
                var mainTitles = new List <Bounds>();
                foreach (var reactantTitle in reactantTitles)
                {
                    mainTitles.Add(reactantTitle);
                    mainTitles.Add(new Bounds());
                }
                if (!reactants.Any())
                {
                    mainTitles.Add(new Bounds()); // gap for arrow
                }
                foreach (var productTitle in productTitles)
                {
                    mainTitles.Add(productTitle);
                    mainTitles.Add(new Bounds());
                }
                // remove trailing space for plus
                if (products.Any())
                {
                    mainTitles.RemoveAt(mainTitles.Count - 1);
                }

                Trace.Assert(mainTitles.Count == mainComp.Count);
                this.mainComp.AddRange(mainTitles);
                this.nRow = 2;
                this.nCol = mainComp.Count / 2;
            }
            else
            {
                this.nRow = 1;
                this.nCol = mainComp.Count;
            }

            this.conditions = conditions;

            // arrow parameters
            this.arrowIdx      = Math.Max(reactants.Count + reactants.Count - 1, 0);
            this.direction     = direction;
            this.arrowHeight   = plus.Height * 2;
            this.minArrowWidth = 4 * arrowHeight;

            mainDim = Dimensions.OfGrid(mainComp,
                                        yOffsets = new double[nRow + 1],
                                        xOffsets = new double[nCol + 1]);

            double middleRequired = Math.Max(prelimSideDim.width, conditions.Width);

            // avoid v. small arrows, we take in to account the padding provided by the arrow head height/length
            if (middleRequired < minArrowWidth - arrowHeight - arrowHeight)
            {
                // adjust x-offset so side components are centered
                double xAdjust = (minArrowWidth - middleRequired) / 2;
                for (int i = 0; i < xOffsetSide.Length; i++)
                {
                    xOffsetSide[i] += xAdjust;
                }
                // need to recenter agents
                if (conditions.Width > prelimSideDim.width)
                {
                    for (int i = 0; i < xOffsetSide.Length; i++)
                    {
                        xOffsetSide[i] += (conditions.Width - prelimSideDim.width) / 2;
                    }
                }
                // update side dims
                this.sideDim = new Dimensions(minArrowWidth, prelimSideDim.height);
                this.condDim = new Dimensions(minArrowWidth, conditions.Height);
            }
            else
            {
                // arrow padding
                for (int i = 0; i < xOffsetSide.Length; i++)
                {
                    xOffsetSide[i] += arrowHeight;
                }

                // need to recenter agents
                if (conditions.Width > prelimSideDim.width)
                {
                    for (int i = 0; i < xOffsetSide.Length; i++)
                    {
                        xOffsetSide[i] += (conditions.Width - prelimSideDim.width) / 2;
                    }
                }

                this.sideDim = new Dimensions(2 * arrowHeight + middleRequired,
                                              prelimSideDim.height);
                this.condDim = new Dimensions(2 * arrowHeight + middleRequired,
                                              conditions.Height);
            }
        }