public void AppendEvent(Mu2e_Event eventToAppend) { this.EventWordCount += eventToAppend.EventWordCount; this.ChNum += eventToAppend.ChNum; foreach (Mu2e_Ch extraChanData in eventToAppend.ChanData) { this.ChanData.Add(extraChanData); } }
public bool ParseInput(byte[] pack, int err = 0) { if (pack.Length <= 0x10) //0x810) //Check if less or equal to 16 bytes (0x10), since that is only the length of a spill header { return(false); //empty event } while (pack[0] == 0x3e) { pack = pack.Skip(1).ToArray(); } try //catch exceptions to prevent program from crashing... usually caused by array index out of bounds due to data problems { this.RecTime = DateTime.Now; //mark the receipt of the spill with the current time #region SpillHeader //spill word count, word: 1 upper, 2 lower int i = 0; //i is the byte offset counter UInt32 t32 = 0; t32 = (UInt32)(pack[i] * 256 * 256 * 256 + //shifting to upper half of upper word pack[i + 1] * 256 * 256 + //shifting to lower half of upper word pack[i + 2] * 256 + //shifting to upper half of lower word pack[i + 3]); //lower half of lower word this.SpillWordCount = t32; //spill trig count, 3 upper, 4 lower i = 4; t32 = (UInt32)(pack[i] * 256 * 256 * 256 + pack[i + 1] * 256 * 256 + pack[i + 2] * 256 + pack[i + 3]); this.SpillTrigCount = t32; if (this.SpillTrigCount > MaxTrigPerSpill) //If the number of triggers is too high, don't bother doing anything else... { if (PP.glbDebug) { Console.WriteLine("too many trig, I quit"); } return(false); } UInt32 event_num_left = this.SpillTrigCount; //Number of events to expect when reading data //spill counter, 5 i = 8; UInt16 t16 = 0; t16 = (UInt16)(pack[i] * 256 + pack[i + 1]); this.SpillCounter = t16; //mask, 6 i = 10; t16 = (UInt16)(pack[i] * 256 + pack[i + 1]); this.Mask = t16; this.ExpectNumCh = 0; for (int p = 0; p < 16; p++) //Get the number of possible channels (from the mask) { if ((Convert.ToUInt16(Math.Pow(2, p)) & this.Mask) == Convert.ToUInt16(Math.Pow(2, p))) { this.ExpectNumCh = (UInt16)(this.ExpectNumCh + 4); } } //board id, 7 i = 12; t16 = (UInt16)(pack[i] * 256 + pack[i + 1]); this.BoardID = t16; //spill status, 8 --- 1st 3-bits only i = 14; t16 = (UInt16)(pack[i] * 256 + pack[i + 1]); this.SpillStatus = t16; if (PP.glbDebug) { System.Console.WriteLine("Spill Word Count: {0}\n", this.SpillWordCount); System.Console.WriteLine("Spill Trig Count: {0}\n", this.SpillTrigCount); System.Console.WriteLine("Spill Counter: {0}\n", this.SpillCounter); System.Console.WriteLine("Channel Count: {0}\n", this.ExpectNumCh); System.Console.WriteLine("Board ID: {0}\n", this.BoardID); } #endregion SpillHeader i = 16; if (pack[i] == 0x3e) //detect if a '>' has been sent between the spill header and event header, if it has then we must skip it { i = 17; } DateTime start_parsing = DateTime.Now; //used to determine how much time is spent parsing the incoming data Mu2e_Event this_event = null; //create reference to mu2e_Event objects //trigger count starts at 1 while (event_num_left > 1) //while there are still events to be read { this_event = new Mu2e_Event(); //set this_event to new event object #region EventHeader //i is 17 at this point for the first event //event word count, word 1 of event header t16 = (UInt16)(pack[i++] * 256 + pack[i++]); this_event.EventWordCount = t16; //event time stamp, 2 upper, 3 lower t32 = (UInt32)(pack[i++] * 256 * 256 * 256 + pack[i++] * 256 * 256 + pack[i++] * 256 + pack[i++]); this_event.EventTimeStamp = t32; if (PP.glbDebug) { Console.WriteLine("time_stamp=" + t32); } //trigger counter, 4 upper, 5 lower t32 = (UInt32)(pack[i++] * 256 * 256 * 256 + pack[i++] * 256 * 256 + pack[i++] * 256 + pack[i++]); this_event.TrigCounter = t32; if (PP.glbDebug) { Console.WriteLine("trig=" + t32); } //event num samples, 6 --- first 8 bits only (1st half of word = 1 byte) t16 = (UInt16)(pack[i++] * 256 + pack[i++]); this_event.NumSamples = t16; //event trig type, 7 --- first 4 bits only t16 = (UInt16)(pack[i++] * 256 + pack[i++]); this_event.TrigType = t16; //event status, 8 --- first 3 bytes only t16 = (UInt16)(pack[i++] * 256 + pack[i++]); this_event.EventStatus = t16; #endregion EventHeader #region EventData if (this_event.NumSamples == 0) { if (PP.glbDebug) { Console.WriteLine("stop!"); } return(false); } int num_ch = Convert.ToInt32(this_event.EventWordCount / this_event.NumSamples); int loop_limit = (num_ch > 15) ? 16 : num_ch; //Stop the event-reading loop from reading beyond 16 channels per FPGA UInt16 ChNum = 0; for (int k = 0; k < loop_limit; k++) { int[] ch_data = new int[this_event.NumSamples]; for (int j = 0; j < this_event.NumSamples; j++) { t16 = (UInt16)(pack[i++] * 256 + pack[i++]); if ((t16 & 0x8000) == 0x8000)//bitwise compare t16 against 'channel format'... if it has the channel flag bit then it must be a channel { if (PP.glbDebug) { Console.WriteLine(t16.ToString("x")); } t16 = (UInt16)(t16 & 0xfff); ChNum = t16; if (PP.glbDebug) { Console.WriteLine("ch: {0} i: {1}", ChNum, i); if (j != 0) { Console.WriteLine(" Something's fucky..."); } } } ch_data[j] = t16; if (ch_data[j] > 0x7ff) { ch_data[j] = ch_data[j] - 0xfff; } //dealing with signed binary numbers } Mu2e_Ch this_ch = new Mu2e_Ch(); this_event.ChNum++; this_ch.data = ch_data; this_ch.num_ch = ChNum; this_event.ChanData.Add(this_ch); } //if (PP.glbDebug) { Console.WriteLine("end of event {0} at time {1}-----------------", this_event.TrigCounter, this_event.EventTimeStamp); } #endregion EventData #region Event Logic & Merging if (spillEvent_Table.ContainsKey(this_event.TrigCounter)) { //update the event already in the table //Reference to the event in the dictionary, which will be updated if (spillEvent_Table.TryGetValue(this_event.TrigCounter, out Mu2e_Event eventToAppend)) { eventToAppend.AppendEvent(this_event); //Add the channel data from this_event to the event already in the table if (eventToAppend.ChNum >= ExpectNumCh) //If the updated event now has the expected number of channels, we are approaching the end of event-reading { event_num_left--; } } else //In the unlikely event that the trigger/event we have found was expected to already exist, but doesn't, stop parsing as there is likely a problem with the data { Console.WriteLine("Error in SpillData:ParseInput:EventLogic&Merging:\n Found a trigger/event that hasn't been seen before, but was expected to already exist."); return(false); } } else //make new dictionary entry { spillEvent_Table.Add(this_event.TrigCounter, this_event); if (loop_limit == this_event.ChNum && this_event.ChNum == ExpectNumCh) //If all of the channels are from just one FPGA, then we shouldn't expect to see any additional correlated events later on in the data { event_num_left--; } } #endregion Event Logic & Merging } foreach (var trigEvent in spillEvent_Table) //Put the list of events from the table into the SpillEvents Object { this.SpillEvents.AddLast(trigEvent.Value); } DateTime end_parsing = DateTime.Now; //Timestamp of when parsing ended TimeSpan time_to_parse = end_parsing.Subtract(start_parsing); //Compute time required to parse data if (PP.glbDebug) { Console.WriteLine("Time to parse {0} events was {1} ms", this.SpillTrigCount, time_to_parse.TotalMilliseconds); } return(true); } catch (Exception e) { Console.WriteLine("Caught exception when parsing spilldata:\n {0}", e); return(false); } }