Exemple #1
0
        public DemodulatedBlock DemodulateBlock(Block b, DemodulationConfig demodulationConfig, int[] tofChannelsToAnalyse)
        {
            if (!b.detectors.Contains("asymmetry"))
            {
                b.AddDetectorsToBlock();
            }

            int blockLength = b.Points.Count;

            DemodulatedBlock db = new DemodulatedBlock(b.TimeStamp, b.Config, demodulationConfig);

            Dictionary <string, double[]> pointDetectorData = new Dictionary <string, double[]>();

            foreach (string d in demodulationConfig.GatedDetectors)
            {
                pointDetectorData.Add(d, GetGatedDetectorData(b, d, demodulationConfig.Gates.GetGate(d)));
            }
            foreach (string d in demodulationConfig.PointDetectors)
            {
                pointDetectorData.Add(d, GetPointDetectorData(b, d));
            }

            Dictionary <string, TOF[]> tofDetectorData = new Dictionary <string, TOF[]>();

            foreach (string d in demodulationConfig.TOFDetectors)
            {
                tofDetectorData.Add(d, GetTOFDetectorData(b, d));
            }

            // ----Demodulate channels----
            // --Build list of modulations--
            List <Modulation> modulations = GetModulations(b);

            // --Work out switch state for each point--
            List <uint> switchStates = GetSwitchStates(modulations);

            // --Calculate state signs for each analysis channel--
            // The first index selects the analysis channel, the second the switchState
            int numStates = (int)Math.Pow(2, modulations.Count);

            int[,] stateSigns = GetStateSigns(numStates);

            // --This is done for each point/gated detector--
            foreach (string d in pointDetectorData.Keys)
            {
                int detectorIndex = b.detectors.IndexOf(d);

                // We obtain one Channel Set for each detector
                ChannelSet <PointWithError> channelSet = new ChannelSet <PointWithError>();

                // Detector calibration
                double calibration = ((TOF)((EDMPoint)b.Points[0]).Shot.TOFs[detectorIndex]).Calibration;

                // Divide points into bins depending on switch state
                List <List <double> > statePoints = new List <List <double> >(numStates);
                for (int i = 0; i < numStates; i++)
                {
                    statePoints.Add(new List <double>(blockLength / numStates));
                }
                for (int i = 0; i < blockLength; i++)
                {
                    statePoints[(int)switchStates[i]].Add(pointDetectorData[b.detectors[detectorIndex]][i]);
                }
                int subLength = blockLength / numStates;

                // For each analysis channel, calculate the mean and standard error, then add to ChannelSet
                for (int channel = 0; channel < numStates; channel++)
                {
                    RunningStatistics stats = new RunningStatistics();
                    for (int subIndex = 0; subIndex < subLength; subIndex++)
                    {
                        double onVal  = 0.0;
                        double offVal = 0.0;
                        for (int i = 0; i < numStates; i++)
                        {
                            if (stateSigns[channel, i] == 1)
                            {
                                onVal += statePoints[i][subIndex];
                            }
                            else
                            {
                                offVal += statePoints[i][subIndex];
                            }
                        }
                        onVal  /= numStates;
                        offVal /= numStates;
                        stats.Push(onVal - offVal);
                    }

                    PointWithError pointWithError = new PointWithError()
                    {
                        Value = stats.Mean, Error = stats.StandardErrorOfSampleMean
                    };

                    // add the channel to the ChannelSet
                    List <string> usedSwitches = new List <string>();
                    for (int i = 0; i < modulations.Count; i++)
                    {
                        if ((channel & (1 << i)) != 0)
                        {
                            usedSwitches.Add(modulations[i].Name);
                        }
                    }
                    string[] channelName = usedSwitches.ToArray();
                    // the SIG channel has a special name
                    if (channel == 0)
                    {
                        channelName = new string[] { "SIG" }
                    }
                    ;
                    channelSet.AddChannel(channelName, pointWithError);
                }

                // Add the ChannelSet to the demodulated block
                db.AddDetector(b.detectors[detectorIndex], calibration, channelSet);
            }

            // --This is done for each TOF detector--
            foreach (string d in tofDetectorData.Keys)
            {
                int detectorIndex = b.detectors.IndexOf(d);

                // We obtain one Channel Set for each detector
                ChannelSet <TOFWithError> channelSet = new ChannelSet <TOFWithError>();

                // Detector calibration
                double calibration = ((TOF)((EDMPoint)b.Points[0]).Shot.TOFs[detectorIndex]).Calibration;

                // Divide TOFs into bins depending on switch state
                List <List <TOF> > statePoints = new List <List <TOF> >(numStates);
                for (int i = 0; i < numStates; i++)
                {
                    statePoints.Add(new List <TOF>(blockLength / numStates));
                }
                for (int i = 0; i < blockLength; i++)
                {
                    statePoints[(int)switchStates[i]].Add(tofDetectorData[b.detectors[detectorIndex]][i]);
                }
                int subLength = blockLength / numStates;

                // For each analysis channel, calculate the mean and standard error, then add to ChannelSet
                foreach (int channel in tofChannelsToAnalyse)
                {
                    TOFAccumulator tofAccumulator = new TOFAccumulator();
                    for (int subIndex = 0; subIndex < subLength; subIndex++)
                    {
                        TOF onTOF  = new TOF();
                        TOF offTOF = new TOF();
                        for (int i = 0; i < numStates; i++)
                        {
                            if (stateSigns[channel, i] == 1)
                            {
                                onTOF += statePoints[i][subIndex];
                            }
                            else
                            {
                                offTOF += statePoints[i][subIndex];
                            }
                        }
                        onTOF  /= numStates;
                        offTOF /= numStates;
                        tofAccumulator.Add(onTOF - offTOF);
                    }

                    // add the channel to the ChannelSet
                    List <string> usedSwitches = new List <string>();
                    for (int i = 0; i < modulations.Count; i++)
                    {
                        if ((channel & (1 << i)) != 0)
                        {
                            usedSwitches.Add(modulations[i].Name);
                        }
                    }
                    string[] channelName = usedSwitches.ToArray();
                    // the SIG channel has a special name
                    if (channel == 0)
                    {
                        channelName = new string[] { "SIG" }
                    }
                    ;
                    channelSet.AddChannel(channelName, tofAccumulator.GetResult());
                }

                // If the detector is a molecule detector, add the special channels
                if (MOLECULE_DETECTORS.Contains(d))
                {
                    channelSet = AppendChannelSetWithSpecialValues(channelSet);
                }

                // Add the ChannelSet to the demodulated block
                db.AddDetector(d, calibration, channelSet);
            }

            return(db);
        }
 private static double[] ConvertPointToArray(PointWithError p)
 {
     return(new double[2] {
         p.Value, p.Error
     });
 }