private BlockStoreDetectorResponse processDetectorQueryAverage(BlockStoreDetectorQuery query, int[] blockIDs) { BlockStoreDetectorResponse dr = new BlockStoreDetectorResponse(); dr.Channels = new Dictionary <string, TOFChannel>(); using (BlockDatabaseDataContext dc = new BlockDatabaseDataContext()) { IEnumerable <DBTOFChannelSet> tcss = from DBTOFChannelSet tcs in dc.DBTOFChannelSets where (tcs.detector == query.Detector) && blockIDs.Contains(tcs.blockID) select tcs; // accumulate the average TCS TOFChannelSetAccumulator tcsa = new TOFChannelSetAccumulator(); foreach (DBTOFChannelSet dbTcs in tcss) { TOFChannelSet t = deserializeTCS(dbTcs.tcsData.ToArray()); tcsa.Add(t); } // TODO: Handle special channels TOFChannelSet averageTCS = tcsa.GetResult(); foreach (string channel in query.Channels) { dr.Channels.Add(channel, (TOFChannel)averageTCS.GetChannel(channel)); } } return(dr); }
private BlockStoreDetectorResponse processDetectorQuery(BlockStoreDetectorQuery query, int blockID) { BlockStoreDetectorResponse dr = new BlockStoreDetectorResponse(); dr.Channels = new Dictionary <string, TOFChannel>(); using (BlockDatabaseDataContext dc = new BlockDatabaseDataContext()) { IEnumerable <DBTOFChannelSet> tcss = from DBTOFChannelSet tcs in dc.DBTOFChannelSets where (tcs.detector == query.Detector) && (tcs.blockID == blockID) select tcs; // there should only be one item - better to check or not? DBTOFChannelSet tc = tcss.First(); TOFChannelSet t = deserializeTCS(tc.tcsData.ToArray()); // TODO: Handle special channels foreach (string channel in query.Channels) { dr.Channels.Add(channel, (TOFChannel)t.GetChannel(channel)); } } return(dr); }
public TOFChannelSet TOFDemodulateBlock(Block b, int detectorIndex, bool allChannels) { // *** demodulate channels *** // ** build the list of modulations ** List<string> modNames = new List<string>(); List<Waveform> modWaveforms = new List<Waveform>(); foreach (AnalogModulation mod in b.Config.AnalogModulations) { modNames.Add(mod.Name); modWaveforms.Add(mod.Waveform); } foreach (DigitalModulation mod in b.Config.DigitalModulations) { modNames.Add(mod.Name); modWaveforms.Add(mod.Waveform); } foreach (TimingModulation mod in b.Config.TimingModulations) { modNames.Add(mod.Name); modWaveforms.Add(mod.Waveform); } // ** work out the switch state for each point ** int blockLength = modWaveforms[0].Length; List<bool[]> wfBits = new List<bool[]>(); foreach (Waveform wf in modWaveforms) wfBits.Add(wf.Bits); List<uint> switchStates = new List<uint>(blockLength); for (int i = 0; i < blockLength; i++) { uint switchState = 0; for (int j = 0; j < wfBits.Count; j++) { if (wfBits[j][i]) switchState += (uint)Math.Pow(2, j); } switchStates.Add(switchState); } // pre-calculate the state signs for each analysis channel // the first index selects the analysis channel, the second the switchState int numStates = (int)Math.Pow(2, modWaveforms.Count); bool[,] stateSigns = new bool[numStates, numStates]; // make a BlockDemodulator just to use its stateSign code // They should probably share a base class. BlockDemodulator bd = new BlockDemodulator(); for (uint i = 0; i < numStates; i++) { for (uint j = 0; j < numStates; j++) { stateSigns[i, j] = (bd.stateSign(j, i) == 1); } } TOFChannelSet tcs = new TOFChannelSet(); // By setting all channels to false only a limited number of channels are analysed, // namely those required to extract the edm (and the correction term). This speeds // up the execution enormously when the BlockTOFDemodulator is used by the // BlockDemodulator for calculating the non-linear channel combinations. //int[] channelsToAnalyse; List<int> channelsToAnalyse; if (allChannels) { //channelsToAnalyse = new int[numStates]; channelsToAnalyse = new List<int>(); //for (int i = 0; i < numStates; i++) channelsToAnalyse[i] = i; for (int i = 0; i < numStates; i++) channelsToAnalyse.Add(i); } else { // just the essential channels - this code is a little awkward because, like // so many bits of the analysis code, it was added long after the original // code was written, and goes against some assumptions that were made back then! int bIndex = modNames.IndexOf("B"); int dbIndex = modNames.IndexOf("DB"); int eIndex = modNames.IndexOf("E"); int rf1fIndex = modNames.IndexOf("RF1F"); int rf2fIndex = modNames.IndexOf("RF2F"); int rf1aIndex = modNames.IndexOf("RF1A"); int rf2aIndex = modNames.IndexOf("RF2A"); int lf1Index = modNames.IndexOf("LF1"); int lf2Index = modNames.IndexOf("LF2"); int sigChannel = 0; int bChannel = (1 << bIndex); int dbChannel = (1 << dbIndex); int ebChannel = (1 << eIndex) + (1 << bIndex); int edbChannel = (1 << eIndex) + (1 << dbIndex); int dbrf1fChannel = (1 << dbIndex) + (1 << rf1fIndex); int dbrf2fChannel = (1 << dbIndex) + (1 << rf2fIndex); int brf1fChannel = (1 << bIndex) + (1 << rf1fIndex); int brf2fChannel = (1 << bIndex) + (1 << rf2fIndex); int edbrf1fChannel = (1 << eIndex) + (1 << dbIndex) + (1 << rf1fIndex); int edbrf2fChannel = (1 << eIndex) + (1 << dbIndex) + (1 << rf2fIndex); int ebdbChannel = (1 << eIndex) + (1 << bIndex) + (1 << dbIndex); int rf1fChannel = (1 << rf1fIndex); int rf2fChannel = (1 << rf2fIndex); int erf1fChannel = (1 << eIndex) + (1 << rf1fIndex); int erf2fChannel = (1 << eIndex) + (1 << rf2fIndex); int rf1aChannel = (1 << rf1aIndex); int rf2aChannel = (1 << rf2aIndex); int dbrf1aChannel = (1 << dbIndex) + (1 << rf1aIndex); int dbrf2aChannel = (1 << dbIndex) + (1 << rf2aIndex); int lf1Channel = (1 << lf1Index); int dblf1Channel = (1 << dbIndex) + (1 << lf1Index); channelsToAnalyse = new List<int>() { sigChannel, bChannel, dbChannel, ebChannel, edbChannel, dbrf1fChannel, dbrf2fChannel, brf1fChannel, brf2fChannel, edbrf1fChannel, edbrf2fChannel, ebdbChannel, rf1fChannel, rf2fChannel, erf1fChannel, erf2fChannel, rf1aChannel, rf2aChannel, dbrf1aChannel, dbrf2aChannel, lf1Channel, dblf1Channel, }; if (lf2Index != -1) // Index = -1 if "LF2" not found { int lf2Channel = (1 << lf2Index); channelsToAnalyse.Add(lf2Channel); int dblf2Channel = (1 << dbIndex) + (1 << lf2Index); channelsToAnalyse.Add(dblf2Channel); } //channelsToAnalyse = new int[] { bChannel, dbChannel, ebChannel, edbChannel, dbrf1fChannel, // dbrf2fChannel, brf1fChannel, brf2fChannel, edbrf1fChannel, edbrf2fChannel, ebdbChannel, // rf1fChannel, rf2fChannel, erf1fChannel, erf2fChannel, rf1aChannel, rf2aChannel, dbrf1aChannel, // dbrf2aChannel, lf1Channel, dblf1Channel, lf2Channel, dblf2Channel //}; } foreach (int channel in channelsToAnalyse) { // generate the Channel TOFChannel tc = new TOFChannel(); TOF tOn = new TOF(); TOF tOff = new TOF(); for (int i = 0; i < blockLength; i++) { if (stateSigns[channel, switchStates[i]]) tOn += ((TOF)((EDMPoint)(b.Points[i])).Shot.TOFs[detectorIndex]); else tOff += ((TOF)((EDMPoint)(b.Points[i])).Shot.TOFs[detectorIndex]); } tOn /= (blockLength / 2); tOff /= (blockLength / 2); tc.On = tOn; tc.Off = tOff; // This "if" is to take care of the case of the "SIG" channel, for which there // is no off TOF. if (tc.Off.Length != 0) tc.Difference = tc.On - tc.Off; else tc.Difference = tc.On; // add the Channel to the ChannelSet List<string> usedSwitches = new List<string>(); for (int i = 0; i < modNames.Count; i++) if ((channel & (1 << i)) != 0) usedSwitches.Add(modNames[i]); string[] channelName = usedSwitches.ToArray(); // the SIG channel has a special name if (channel == 0) channelName = new string[] {"SIG"}; tcs.AddChannel(channelName, tc); } // ** add the special channels ** // extract the TOFChannels that we need. TOFChannel c_eb = (TOFChannel)tcs.GetChannel(new string[] { "E", "B" }); TOFChannel c_edb = (TOFChannel)tcs.GetChannel(new string[] {"E", "DB"}); TOFChannel c_dbrf1f = (TOFChannel)tcs.GetChannel(new string[] { "DB", "RF1F" }); TOFChannel c_dbrf2f = (TOFChannel)tcs.GetChannel(new string[] { "DB", "RF2F" }); TOFChannel c_b = (TOFChannel)tcs.GetChannel(new string[] { "B" }); TOFChannel c_db = (TOFChannel)tcs.GetChannel(new string[] { "DB" }); TOFChannel c_sig = (TOFChannel)tcs.GetChannel(new string[] { "SIG" }); TOFChannel c_brf1f = (TOFChannel)tcs.GetChannel(new string[] { "B", "RF1F" }); TOFChannel c_brf2f = (TOFChannel)tcs.GetChannel(new string[] { "B", "RF2F" }); TOFChannel c_edbrf1f = (TOFChannel)tcs.GetChannel(new string[] { "E", "DB", "RF1F" }); TOFChannel c_edbrf2f = (TOFChannel)tcs.GetChannel(new string[] { "E", "DB", "RF2F" }); TOFChannel c_ebdb= (TOFChannel)tcs.GetChannel(new string[] { "E", "B", "DB" }); TOFChannel c_rf1f = (TOFChannel)tcs.GetChannel(new string[] { "RF1F" }); TOFChannel c_rf2f = (TOFChannel)tcs.GetChannel(new string[] { "RF2F" }); TOFChannel c_erf1f = (TOFChannel)tcs.GetChannel(new string[] { "E", "RF1F" }); TOFChannel c_erf2f = (TOFChannel)tcs.GetChannel(new string[] { "E", "RF2F" }); TOFChannel c_rf1a = (TOFChannel)tcs.GetChannel(new string[] { "RF1A" }); TOFChannel c_rf2a = (TOFChannel)tcs.GetChannel(new string[] { "RF2A" }); TOFChannel c_dbrf1a = (TOFChannel)tcs.GetChannel(new string[] { "DB", "RF1A" }); TOFChannel c_dbrf2a = (TOFChannel)tcs.GetChannel(new string[] { "DB", "RF2A" }); TOFChannel c_lf1 = (TOFChannel)tcs.GetChannel(new string[] { "LF1" }); TOFChannel c_dblf1 = (TOFChannel)tcs.GetChannel(new string[] { "DB", "LF1" }); TOFChannel c_lf2; TOFChannel c_dblf2; if (modNames.IndexOf("LF2") == -1) // Index = -1 if "LF2" not found { TOF tofTemp = new TOF(); TOFChannel tcTemp = new TOFChannel(); // For many blocks there is no LF2 channel (and hence switch states). // To get around this problem I will populate the TOFChannel with "SIG" // It will then be obvious in the analysis when LF2 takes on real values. for (int i = 0; i < blockLength; i++) { tofTemp += ((TOF)((EDMPoint)(b.Points[i])).Shot.TOFs[detectorIndex]); } tofTemp /= (blockLength / 2); tcTemp.On = tofTemp; tcTemp.Off = tofTemp; tcTemp.Difference = tofTemp; c_lf2 = tcTemp; c_dblf2 = tcTemp; } else { c_lf2 = (TOFChannel)tcs.GetChannel(new string[] { "LF2" }); c_dblf2 = (TOFChannel)tcs.GetChannel(new string[] { "DB", "LF2" }); } // work out some intermediate terms for the full, corrected edm. The names // refer to the joint power of c_db and c_b in the term. TOFChannel squaredTerms = (((c_db * c_db) - (c_dbrf1f * c_dbrf1f) - (c_dbrf2f * c_dbrf2f)) * c_eb) - (c_b * c_db * c_edb); // this is missing the term /beta c_db c_ebdb at the moment, mainly because // I've no idea what beta should be. TOFChannel linearTerms = (c_b * c_dbrf1f * c_edbrf1f) + (c_b * c_dbrf2f * c_edbrf2f) - (c_db * c_brf1f * c_edbrf1f) - (c_db * c_brf2f * c_edbrf2f); TOFChannel preDenominator = (c_db * c_db * c_db) + (c_dbrf1f * c_edb * c_edbrf1f) + (c_dbrf1f * c_edb * c_edbrf1f) + (c_dbrf2f * c_edb * c_edbrf2f) + (c_dbrf2f * c_edb * c_edbrf2f) - c_db * ( (c_dbrf1f * c_dbrf1f) + (c_dbrf2f * c_dbrf2f) + (c_edb * c_edb) + (c_edbrf1f * c_edbrf1f) + (c_edbrf2f * c_edbrf2f) ); // it's important when working out the non-linear channel // combinations to always keep them dimensionless. If you // don't you'll run into trouble with integral vs. average // signal. TOFChannel edmDB = c_eb / c_db; tcs.AddChannel(new string[] { "EDMDB" }, edmDB); // The corrected edm channel. This should be proportional to the edm phase. TOFChannel edmCorrDB = (squaredTerms + linearTerms) / preDenominator; tcs.AddChannel(new string[] { "EDMCORRDB" }, edmCorrDB); // It's useful to have an estimate of the size of the correction. Here // we return the difference between the corrected edm channel and the // naive guess, edmDB. TOFChannel correctionDB = edmCorrDB - edmDB; tcs.AddChannel(new string[] { "CORRDB" }, correctionDB); // The "old" correction that just corrects for the E-correlated amplitude change. // This is included in the dblocks for debugging purposes. TOFChannel correctionDB_old = (c_edb * c_b) / (c_db * c_db); tcs.AddChannel(new string[] { "CORRDB_OLD" }, correctionDB_old); TOFChannel edmCorrDB_old = edmDB - correctionDB_old; tcs.AddChannel(new string[] { "EDMCORRDB_OLD" }, edmCorrDB_old); // Normalised RFxF channels. TOFChannel rf1fDB = c_rf1f / c_db; tcs.AddChannel(new string[] { "RF1FDB" }, rf1fDB); TOFChannel rf2fDB = c_rf2f / c_db; tcs.AddChannel(new string[] { "RF2FDB" }, rf2fDB); // And RFxF.DB channels, again normalised to DB. The naming of these channels is quite // unfortunate, but it's just tough. TOFChannel rf1fDBDB = c_dbrf1f / c_db; tcs.AddChannel(new string[] { "RF1FDBDB" }, rf1fDBDB); TOFChannel rf2fDBDB = c_dbrf2f / c_db; tcs.AddChannel(new string[] { "RF2FDBDB" }, rf2fDBDB); // Normalised RFxAchannels. TOFChannel rf1aDB = c_rf1a / c_db; tcs.AddChannel(new string[] { "RF1ADB" }, rf1aDB); TOFChannel rf2aDB = c_rf2a / c_db; tcs.AddChannel(new string[] { "RF2ADB" }, rf2aDB); // And RFxA.DB channels, again normalised to DB. The naming of these channels is quite // unfortunate, but it's just tough. TOFChannel rf1aDBDB = c_dbrf1a / c_db; tcs.AddChannel(new string[] { "RF1ADBDB" }, rf1aDBDB); TOFChannel rf2aDBDB = c_dbrf2a / c_db; tcs.AddChannel(new string[] { "RF2ADBDB" }, rf2aDBDB); // the E.RFxF channels, normalized to DB TOFChannel erf1fDB = c_erf1f / c_db; tcs.AddChannel(new string[] { "ERF1FDB" }, erf1fDB); TOFChannel erf2fDB = c_erf2f / c_db; tcs.AddChannel(new string[] { "ERF2FDB" }, erf2fDB); // the E.RFxF.DB channels, normalized to DB, again dodgy naming convention. TOFChannel erf1fDBDB = c_edbrf1f / c_db; tcs.AddChannel(new string[] { "ERF1FDBDB" }, erf1fDBDB); TOFChannel erf2fDBDB = c_edbrf2f / c_db; tcs.AddChannel(new string[] { "ERF2FDBDB" }, erf2fDBDB); // the LF1 channel, normalized to DB TOFChannel lf1DB = c_lf1 / c_db; tcs.AddChannel(new string[] { "LF1DB" }, lf1DB); TOFChannel lf1DBDB = c_dblf1 / c_db; tcs.AddChannel(new string[] { "LF1DBDB" }, lf1DBDB); // the LF2 channel, normalized to DB TOFChannel lf2DB = c_lf2 / c_db; tcs.AddChannel(new string[] { "LF2DB" }, lf2DB); TOFChannel lf2DBDB = c_dblf2 / c_db; tcs.AddChannel(new string[] { "LF2DBDB" }, lf2DBDB); TOFChannel bDB = c_b / c_db; tcs.AddChannel(new string[] { "BDB" }, bDB); // we also need to extract the rf-step induced phase shifts. These come out in the // B.RFxF channels, but like the edm, need to be corrected. I'm going to use just the // simplest level of correction for these. TOFChannel brf1fCorrDB = (c_brf1f / c_db) - ((c_b * c_dbrf1f) / (c_db * c_db)); tcs.AddChannel(new string[] { "BRF1FCORRDB" }, brf1fCorrDB); TOFChannel brf2fCorrDB = (c_brf2f / c_db) - ((c_b * c_dbrf2f) / (c_db * c_db)); tcs.AddChannel(new string[] { "BRF2FCORRDB" }, brf2fCorrDB); //Some extra channels for various shot noise calculations, these are a bit weird tcs.AddChannel(new string[] { "SIGNL" }, c_sig); tcs.AddChannel(new string[] { "ONEOVERDB" }, 1/c_db); TOFChannel dbSigNL = new TOFChannel(); dbSigNL.On = c_db.On/c_sig.On; dbSigNL.Off = c_db.Off/c_sig.On;; dbSigNL.Difference = c_db.Difference / c_sig.Difference; tcs.AddChannel(new string[] { "DBSIG" }, dbSigNL); TOFChannel dbdbSigSigNL = dbSigNL * dbSigNL; tcs.AddChannel(new string[] { "DBDBSIGSIG" }, dbdbSigSigNL); TOFChannel SigdbdbNL = new TOFChannel(); SigdbdbNL.On = c_sig.On / ( c_db.On* c_db.On); SigdbdbNL.Off = c_sig.On / ( c_db.Off * c_db.Off); SigdbdbNL.Difference = c_sig.Difference / (c_db.Difference * c_db.Difference); tcs.AddChannel(new string[] { "SIGDBDB" }, SigdbdbNL); return tcs; }