private static RecognitionResults RecognizeImage(double[] input, long inputToken, int width, int height, int finalResolution, TrainedRecognizer[] recognizers, LifeEventToVector lifeEvents, ConvolutionBase2D convolution, bool isColor)
        {
            if (recognizers == null)
            {
                return new RecognitionResults(inputToken, new double[lifeEvents.Types.Length]);
            }

            double[] normalized = NormalizeInput(input, width, height, finalResolution, convolution, isColor);

            foreach (var recognizer in recognizers)
            {
                double[] output = recognizer.Network.Compute(normalized);

                //TODO: Analyze outputs of all the recognizers to come up with a final result.  Can't just take the average -- if they all
                //agree, that's great.  But disagreement should have a zero output (or at least a very weak output)
                return new RecognitionResults(inputToken, output);
            }

            throw new ApplicationException("finish this");
        }
        //TODO: This should store results in dna
        public void AssignOutputs(LifeEventToVector lifeEvents)
        {
            if (_lifeEvents != null)
            {
                throw new InvalidOperationException("LifeEvents can only be assigned once");
            }

            _lifeEvents = lifeEvents;
            lifeEvents.EventOccurred += LifeEvents_EventOccurred;

            // Build the neurons
            _outputNeurons = CreateNeurons(this.DNA, _itemOptions, lifeEvents);
        }
        private static Neuron_SensorPosition[] CreateNeurons(ShipPartDNA dna, ItemOptions itemOptions, LifeEventToVector lifeEvents)
        {
            //TODO: Instead of just having a single output neuron for each life event type, report the type at location?
            //For example: the camera's input is a square, so have a grid of blocks.  The output grid doesn't need to be very high
            //resolution, maybe 3x3 up to 5x5.  Each block would be a line of neurons perpendicular to the square

            double radius = (dna.Scale.X + dna.Scale.Y + dna.Scale.Z) / (3d * 2d);		// xyz should all be the same anyway

            Vector3D[] positions = Brain.GetNeuronPositions_Line2D(null, lifeEvents.Types.Length, radius);

            return positions.
                Select(o => new Neuron_SensorPosition(o.ToPoint(), true)).
                ToArray();
        }