private static bool IsSame(BrainRGBRecognizer.TrainerInput data1, BrainRGBRecognizer.TrainerInput data2)
        {
            if (data1 == null && data2 == null)
            {
                return true;
            }
            else if (data1 == null || data2 == null)
            {
                return false;
            }

            return data1.Token == data2.Token;      // I decided to just add a token

            //if (data1.Width != data2.Width || data1.Height != data2.Height)
            //{
            //    return false;
            //}
            //else if (data1.ImportantEvents.Length != data2.ImportantEvents.Length)
            //{
            //    return false;
            //}

            //// Don't want to compare every pixel
            //int step = 13;
            //if (data1.Width % step == 0)
            //{
            //    step = 11;      // it's not a big deal if step is a multiple of width.  I would just prefer the samples to not all be in the same column
            //}

            //for (int cntr = 0; cntr < data1.ImportantEvents.Length; cntr++)
            //{
            //    if (!IsSame(data1.ImportantEvents[cntr].Item1, data2.ImportantEvents[cntr].Item1))
            //    {
            //        return false;
            //    }
            //    else if (!IsSame(data1.ImportantEvents[cntr].Item2, data2.ImportantEvents[cntr].Item2, step))
            //    {
            //        return false;
            //    }
            //}

            //return true;
        }
        //TODO: This should store results in dna
        public static void AssignCameras(BrainRGBRecognizer[] recognizers, CameraColorRGB[] cameras)
        {
            if (cameras != null)
            {
                foreach (CameraColorRGB camera in cameras)
                {
                    camera.NeuronContainerType = NeuronContainerType.Sensor;
                }
            }

            if (recognizers == null || recognizers.Length == 0)
            {
                return;
            }

            foreach (BrainRGBRecognizer recognizer in recognizers)
            {
                recognizer.SetCamera(null);
            }

            if (cameras == null || cameras.Length == 0)
            {
                return;
            }

            // Call linker
            LinkItem[] recogItems = recognizers.
                Select(o => new LinkItem(o.Position, o.Radius)).
                ToArray();

            LinkItem[] cameraItems = cameras.
                Select(o => new LinkItem(o.Position, o.Radius)).
                ToArray();

            Tuple<int, int>[] links = ItemLinker.Link_1_2(cameraItems, recogItems, new ItemLinker_OverflowArgs());

            // Assign cameras
            foreach (var link in links)
            {
                recognizers[link.Item2].SetCamera(cameras[link.Item1]);
                cameras[link.Item1].NeuronContainerType = NeuronContainerType.None;     // this recognizer will now be this camera's output
            }
        }
        private static void DrawTrainingData_Set(Grid grid, BrainRGBRecognizer.TrainerInput trainingData)
        {
            var byType = trainingData.ImportantEvents.
                ToLookup(o => o.Item1.Type).
                OrderBy(o => o.Key.ToString()).
                ToArray();

            foreach (var typeSet in byType)
            {
                IEnumerable<double[]> examples = typeSet.
                    OrderBy(o => o.Item1.Time).     // may want to order descending by strength
                    Select(o => o.Item2);

                DrawTrainingData_Classification(grid, typeSet.Key.ToString(), examples, trainingData.Width, trainingData.Height, trainingData.IsColor);
            }

            if (trainingData.UnimportantEvents.Length > 0)
            {
                DrawTrainingData_Classification(grid, "<nothing>", trainingData.UnimportantEvents, trainingData.Width, trainingData.Height, trainingData.IsColor);
            }
        }