Example #1
0
        /// <summary>
        /// ResetForConcatenation() clears metadata for a new experiment,
        /// but preserves present histogram array so subsequent data can be added.
        /// </summary>
        public void ResetForConcatenation()
        {
            int i;
            RossiAlphaCircularNeutronEvent thisEvent, nextEvent;

#if USE_SPINTIME
            spinTimeTotal = 0;
            spinTimeReady = false;
#endif

            //break the circular references, so garbage collector will do its thing
            nextEvent = theEventCircularLinkedList;
            while (nextEvent != null)
            {
                thisEvent      = nextEvent;
                nextEvent      = thisEvent.next;
                thisEvent.next = null;
            }

            //create the circular linked list
            theEventCircularLinkedList = new RossiAlphaCircularNeutronEvent(0);    //create the first element in the list
            startOfList = theEventCircularLinkedList;                              //set the head of the list to this first element
            endOfList   = theEventCircularLinkedList;                              //set the tail of thelist to this first element
            for (i = 1; i < RawAnalysisProperties.circularListBlockIncrement; i++) //as a starter, put RawAnalysisProperties.circularListBlockIncrement structures in the list
            {
                endOfList.next = new RossiAlphaCircularNeutronEvent(i);            //create the next new struct at the end of the tail
                endOfList      = endOfList.next;                                   //move the tail to this new stuct
            }
            numObjectsInCircularLinkedList = RawAnalysisProperties.circularListBlockIncrement;
            endOfList.next = startOfList; //close the loop, connecting the tail back to the head
            endOfList      = startOfList; //set the head and tail to the first empty structure

            numCircuits      = 0;
            isReadyToAnalyze = true;
        }
        public RossiAlphaCircularNeutronEvent(int identifyingNumber)
        {
            //initialize the linked-list information
            next = null;

            //store the identifier for this structure
            serialNumber = identifyingNumber;
        }
Example #3
0
        public RossiAlphaCircularNeutronEvent(int identifyingNumber)
        {
            //initialize the linked-list information
            next = null;

            //store the identifier for this structure
            serialNumber = identifyingNumber;
        }
Example #4
0
        public RossiAlphaCircularStackAnalysis(UInt64 gateWidth)
        {
            int i;

            isReadyToAnalyze = false;

#if USE_SPINTIME
            spinTimeTotal = 0;
            spinTimeStart = 0;
            spinTimeReady = false;
#endif

            rossiAlphaGateWidth         = gateWidth;
            rossiAlphaWindowWidth       = ((UInt64)(RawAnalysisProperties.numRAGatesPerWindow)) * gateWidth;
            totalRossiAlphaAnalysisTime = 0;

            for (i = 0; i < RawAnalysisProperties.numRAGatesPerWindow; i++)
            {
                neutronsPerRossiAlphaGate[i] = 0;
            }

            //initialize the event inputs
            inputEventTime        = new UInt64[RawAnalysisProperties.maxEventsPerBlock];
            inputEventNeutrons    = new UInt32[RawAnalysisProperties.maxEventsPerBlock];
            inputEventNumNeutrons = new UInt32[RawAnalysisProperties.maxEventsPerBlock];
            numEventsThisBlock    = 0;

            //create the circular linked list
            theEventCircularLinkedList = new RossiAlphaCircularNeutronEvent(0);    //create the first element in the list
            startOfList = theEventCircularLinkedList;                              //set the head of the list to this first element
            endOfList   = theEventCircularLinkedList;                              //set the tail of thelist to this first element
            for (i = 1; i < RawAnalysisProperties.circularListBlockIncrement; i++) //as a starter, put RawAnalysisProperties.circularListBlockIncrement structures in the list
            {
                endOfList.next = new RossiAlphaCircularNeutronEvent(i);            //create the next new struct at the end of the tail
                endOfList      = endOfList.next;                                   //move the tail to this new stuct
            }
            numObjectsInCircularLinkedList = RawAnalysisProperties.circularListBlockIncrement;
            endOfList.next = startOfList; //close the loop, connecting the tail back to the head
            endOfList      = startOfList; //set the head and tail to the first empty structure

            numCircuits = 0;

            //Set Up the RAC BackgroundWorker
            keepRunning      = true;
            isReadyToAnalyze = false;
            RACWorker        = new BackgroundWorker();
            RACWorker.WorkerSupportsCancellation = false;  //it either processes a neutron event, or it doesn't.
            RACWorker.DoWork += new DoWorkEventHandler(RACWorker_DoWork);
            RACWorker.RunWorkerAsync();

            //pause until the RAcWorker is working
            while (RACWorker.IsBusy == false)
            {
                Thread.Sleep(1);
            }
        }
Example #5
0
        /// <summary>
        /// ResetCompletely() clears results and sets metadata for new data,
        /// such as running a new experiment or reading a new NCD file
        /// </summary>
        public void ResetCompletely(bool closeCounters)
        {
            int i;
            RossiAlphaCircularNeutronEvent thisEvent, nextEvent;

#if USE_SPINTIME
            spinTimeTotal = 0;
            spinTimeReady = false;
#endif

            for (i = 0; i < RawAnalysisProperties.numRAGatesPerWindow; i++)
            {
                neutronsPerRossiAlphaGate[i] = 0;
            }

            //break the circular references, so garbage collector will do its thing
            nextEvent = theEventCircularLinkedList;
            while (nextEvent != null)
            {
                thisEvent      = nextEvent;
                nextEvent      = thisEvent.next;
                thisEvent.next = null;
            }

            theEventCircularLinkedList = null;
            startOfList = null;
            endOfList   = null;
            numObjectsInCircularLinkedList = 0;

            if (closeCounters)
            {
                keepRunning      = false;
                isReadyToAnalyze = false;
                waitingForMessage.Set();
            }
            else
            {
                //create the circular linked list
                theEventCircularLinkedList = new RossiAlphaCircularNeutronEvent(0);    //create the first element in the list
                startOfList = theEventCircularLinkedList;                              //set the head of the list to this first element
                endOfList   = theEventCircularLinkedList;                              //set the tail of thelist to this first element
                for (i = 1; i < RawAnalysisProperties.circularListBlockIncrement; i++) //as a starter, put RawAnalysisProperties.circularListBlockIncrement structures in the list
                {
                    endOfList.next = new RossiAlphaCircularNeutronEvent(i);            //create the next new struct at the end of the tail
                    endOfList      = endOfList.next;                                   //move the tail to this new stuct
                }
                numObjectsInCircularLinkedList = RawAnalysisProperties.circularListBlockIncrement;
                endOfList.next = startOfList; //close the loop, connecting the tail back to the head
                endOfList      = startOfList; //set the head and tail to the first empty structure

                numCircuits      = 0;
                isReadyToAnalyze = true;
            }
        }
        void RACWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            ulong deltaTimeInQueue;

            string threadName = "RossiAlphaAnalyzer_" + rossiAlphaGateWidth;
            Thread.CurrentThread.Name = threadName;

            #if USE_SPINTIME
            spinTimeReady = false;
            #endif

            while (keepRunning == true)
            {
                isReadyToAnalyze = true;

            #if USE_SPINTIME
                if (spinTimeReady)
                {
                    StartSpinCount();
                }
            #endif

                waitingForMessage.Wait();  //wait for some other thread to place neutron data in this object and signal this worker to analyze

            #if USE_SPINTIME
                if (spinTimeReady)
                {
                    EndSpinCount();
                }
                else
                {
                   spinTimeReady = true;
                }
            #endif

                if (keepRunning == true)
                {
                    int i, j;
                    ulong eventTime;
                    uint eventNeutrons;
                    uint eventNumNeutrons;
                    RossiAlphaCircularNeutronEvent anEvent;
                    RossiAlphaCircularNeutronEvent nextEvent;

                    for (j = 0; j < numEventsThisBlock && !csa.IsQuitRequested; j++)
                    {
                        eventTime = inputEventTime[j];
                        eventNeutrons = inputEventNeutrons[j];
                        eventNumNeutrons = inputEventNumNeutrons[j];

                        //fill in these new data at the tail of the circular linked list,
                        //remembering that endOfNeutronEventList points to the next EMPTY struct in the list
                        //INCLUDING at the beginning when the head and tail point to the same struct
                        endOfList.FillEventWithData(eventTime, eventNeutrons, eventNumNeutrons);

                        //check to see if the circular list will overflow
                        if (endOfList.next.serialNumber == startOfList.serialNumber)
                        {

                            //if stack would overflow, add RawAnalysisProperties.circularListBlockIncrement neutron events at this spot in the stack...
                            anEvent = endOfList;
                            nextEvent = endOfList.next;
                            for (i = 0; i < RawAnalysisProperties.circularListBlockIncrement; i++)
                            {
                                anEvent.next = new RossiAlphaCircularNeutronEvent(i + numObjectsInCircularLinkedList);
                                anEvent = anEvent.next;
                            }
                            anEvent.next = nextEvent;  //patch the circular linked list back together
                            numObjectsInCircularLinkedList += RawAnalysisProperties.circularListBlockIncrement;  //increase the record of the number of structs in the circular list
                        }

                        //move endOfNeutronEventList to the next empty struct
                        endOfList = endOfList.next;

                        //for fun, count how many times we have lapped the circular list in this experiment
                        if (endOfList.serialNumber == 0)
                        {
                            numCircuits++;
                        }

                        //see if oldest event in the queue is expiring,
                        //and while there are expiring events calculate the RossiAlpha statistics for those events
                        deltaTimeInQueue = eventTime - startOfList.eventTime;
                        while (deltaTimeInQueue > rossiAlphaWindowWidth)
                        {
                            //record the time of the expiring gate from the startOfList event, the total measured time for this experiment
                            totalRossiAlphaAnalysisTime = startOfList.eventTime + rossiAlphaWindowWidth;

                            //do RossiAlpha analysis here, accumulating statistics
                            //add up how many neutrons there were in each RossiAlpha gate from the time of the expiring event
                            int whichBin;
                            ulong deltaTime;

                            //skip the event at the head of the list.
                            //To match data from the legacy code, start with the neutron event following this expiring head event.
                            anEvent = startOfList.next;
                            while (anEvent.serialNumber != endOfList.serialNumber)  //...that is, until we reach the end of the list...
                            {
                                //Find the lowest bin with end time greater than the time of anEvent.
                                deltaTime = anEvent.eventTime - startOfList.eventTime;
                                whichBin = (int)(Math.Ceiling((double)deltaTime / (double)rossiAlphaGateWidth) + 0.1);

                                if (whichBin < RawAnalysisProperties.numRAGatesPerWindow)  //then this event falls into a bin; add this event's neutrons to that bin
                                {
                                    neutronsPerRossiAlphaGate[whichBin] += anEvent.numNeutrons;
                                    //go to the next event
                                    anEvent = anEvent.next;
                                }
                                else
                                {
                                    anEvent = endOfList;  //abort the loop by going to the end of the list
                                }
                            }

                            //remove expiring oldest event from the stack
                            startOfList = startOfList.next;

                            //re-calculate the delta time in the stack
                            deltaTimeInQueue = eventTime - startOfList.eventTime;
                        }  //END of handling an individual NeutronEvent

                        if (csa.IsQuitRequested)
                            break;
                    }  //END of handling this block of events

                    //prepare this thread's wait condition so will wait for a message
                    //before telling master thread this thread's analysis is complete
                    waitingForMessage.Reset();

                }  //END of if(keepRunning)
                else
                {
                    //The master thread has cleared the keepRunning flag, so this worker is exiting
                    //Do any cleanup etc. here.
                }
            }  //END of while(keepRunning)
        }
        /// <summary>
        /// ResetForConcatenation() clears metadata for a new experiment,
        /// but preserves present histogram array so subsequent data can be added.
        /// </summary>
        public void ResetForConcatenation()
        {
            int i;
            RossiAlphaCircularNeutronEvent thisEvent, nextEvent;

            #if USE_SPINTIME
            spinTimeTotal = 0;
            spinTimeReady = false;
            #endif

            //break the circular references, so garbage collector will do its thing
            nextEvent = theEventCircularLinkedList;
            while (nextEvent != null)
            {
                thisEvent = nextEvent;
                nextEvent = thisEvent.next;
                thisEvent.next = null;
            }

            //create the circular linked list
            theEventCircularLinkedList = new RossiAlphaCircularNeutronEvent(0);  //create the first element in the list
            startOfList = theEventCircularLinkedList;  //set the head of the list to this first element
            endOfList = theEventCircularLinkedList;  //set the tail of thelist to this first element
            for (i = 1; i < RawAnalysisProperties.circularListBlockIncrement; i++)  //as a starter, put RawAnalysisProperties.circularListBlockIncrement structures in the list
            {
                endOfList.next = new RossiAlphaCircularNeutronEvent(i);  //create the next new struct at the end of the tail
                endOfList = endOfList.next;  //move the tail to this new stuct
            }
            numObjectsInCircularLinkedList = RawAnalysisProperties.circularListBlockIncrement;
            endOfList.next = startOfList;  //close the loop, connecting the tail back to the head
            endOfList = startOfList;  //set the head and tail to the first empty structure

            numCircuits = 0;
            isReadyToAnalyze = true;
        }
        /// <summary>
        /// ResetCompletely() clears results and sets metadata for new data,
        /// such as running a new experiment or reading a new NCD file
        /// </summary>
        public void ResetCompletely(bool closeCounters)
        {
            int i;
            RossiAlphaCircularNeutronEvent thisEvent, nextEvent;

            #if USE_SPINTIME
            spinTimeTotal = 0;
            spinTimeReady = false;
            #endif

            for (i = 0; i < RawAnalysisProperties.numRAGatesPerWindow; i++)
            {
                neutronsPerRossiAlphaGate[i] = 0;
            }

            //break the circular references, so garbage collector will do its thing
            nextEvent = theEventCircularLinkedList;
            while (nextEvent != null)
            {
                thisEvent = nextEvent;
                nextEvent = thisEvent.next;
                thisEvent.next = null;
            }

            theEventCircularLinkedList = null;
            startOfList = null;
            endOfList = null;
            numObjectsInCircularLinkedList = 0;

            if (closeCounters)
            {
                keepRunning = false;
                isReadyToAnalyze = false;
                waitingForMessage.Set();
            }
            else
            {
                //create the circular linked list
                theEventCircularLinkedList = new RossiAlphaCircularNeutronEvent(0);  //create the first element in the list
                startOfList = theEventCircularLinkedList;  //set the head of the list to this first element
                endOfList = theEventCircularLinkedList;  //set the tail of thelist to this first element
                for (i = 1; i < RawAnalysisProperties.circularListBlockIncrement; i++)  //as a starter, put RawAnalysisProperties.circularListBlockIncrement structures in the list
                {
                    endOfList.next = new RossiAlphaCircularNeutronEvent(i);  //create the next new struct at the end of the tail
                    endOfList = endOfList.next;  //move the tail to this new stuct
                }
                numObjectsInCircularLinkedList = RawAnalysisProperties.circularListBlockIncrement;
                endOfList.next = startOfList;  //close the loop, connecting the tail back to the head
                endOfList = startOfList;  //set the head and tail to the first empty structure

                numCircuits = 0;
                isReadyToAnalyze = true;
            }
        }
        public RossiAlphaCircularStackAnalysis(UInt64 gateWidth)
        {
            int i;

            isReadyToAnalyze = false;

            #if USE_SPINTIME
            spinTimeTotal = 0;
            spinTimeStart = 0;
            spinTimeReady = false;
            #endif

            rossiAlphaGateWidth = gateWidth;
            rossiAlphaWindowWidth = ((UInt64)(RawAnalysisProperties.numRAGatesPerWindow)) * gateWidth;
            totalRossiAlphaAnalysisTime = 0;

            for (i = 0; i < RawAnalysisProperties.numRAGatesPerWindow; i++)
            {
                neutronsPerRossiAlphaGate[i] = 0;
            }

            //initialize the event inputs
            inputEventTime = new ulong[RawAnalysisProperties.maxEventsPerBlock];
            inputEventNeutrons = new uint[RawAnalysisProperties.maxEventsPerBlock];
            inputEventNumNeutrons = new uint[RawAnalysisProperties.maxEventsPerBlock];
            numEventsThisBlock = 0;

            //create the circular linked list
            theEventCircularLinkedList = new RossiAlphaCircularNeutronEvent(0);  //create the first element in the list
            startOfList = theEventCircularLinkedList;  //set the head of the list to this first element
            endOfList = theEventCircularLinkedList;  //set the tail of thelist to this first element
            for (i = 1; i < RawAnalysisProperties.circularListBlockIncrement; i++)  //as a starter, put RawAnalysisProperties.circularListBlockIncrement structures in the list
            {
                endOfList.next = new RossiAlphaCircularNeutronEvent(i);  //create the next new struct at the end of the tail
                endOfList = endOfList.next;  //move the tail to this new stuct
            }
            numObjectsInCircularLinkedList = RawAnalysisProperties.circularListBlockIncrement;
            endOfList.next = startOfList;  //close the loop, connecting the tail back to the head
            endOfList = startOfList;  //set the head and tail to the first empty structure

            numCircuits = 0;

            //Set Up the RAC BackgroundWorker
            keepRunning = true;
            isReadyToAnalyze = false;
            RACWorker = new BackgroundWorker();
            RACWorker.WorkerSupportsCancellation = false;  //it either processes a neutron event, or it doesn't.
            RACWorker.DoWork += new DoWorkEventHandler(RACWorker_DoWork);
            RACWorker.RunWorkerAsync();

            //pause until the RAcWorker is working
            while (RACWorker.IsBusy == false)
            {
                Thread.Sleep(1);
            }
        }
Example #10
0
        void RACWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            UInt64 deltaTimeInQueue;

            String threadName = "RossiAlphaAnalyzer_" + rossiAlphaGateWidth;

            Thread.CurrentThread.Name = threadName;

#if USE_SPINTIME
            spinTimeReady = false;
#endif

            while (keepRunning == true)
            {
                isReadyToAnalyze = true;

#if USE_SPINTIME
                if (spinTimeReady)
                {
                    StartSpinCount();
                }
#endif

                waitingForMessage.Wait();  //wait for some other thread to place neutron data in this object and signal this worker to analyze

#if USE_SPINTIME
                if (spinTimeReady)
                {
                    EndSpinCount();
                }
                else
                {
                    spinTimeReady = true;
                }
#endif

                if (keepRunning == true)
                {
                    UInt64 eventTime;
                    UInt32 eventNeutrons;
                    UInt32 eventNumNeutrons;
                    int    j;

                    for (j = 0; j < numEventsThisBlock; j++)
                    {
                        eventTime        = inputEventTime[j];
                        eventNeutrons    = inputEventNeutrons[j];
                        eventNumNeutrons = inputEventNumNeutrons[j];

                        //fill in these new data at the tail of the circular linked list,
                        //remembering that endOfNeutronEventList points to the next EMPTY struct in the list
                        //INCLUDING at the beginning when the head and tail point to the same struct
                        endOfList.FillEventWithData(eventTime, eventNeutrons, eventNumNeutrons);

                        //check to see if the circular list will overflow
                        if (endOfList.next.serialNumber == startOfList.serialNumber)
                        {
                            int i;
                            RossiAlphaCircularNeutronEvent anEvent;
                            RossiAlphaCircularNeutronEvent nextEvent;

                            //if stack would overflow, add RawAnalysisProperties.circularListBlockIncrement neutron events at this spot in the stack...
                            anEvent   = endOfList;
                            nextEvent = endOfList.next;
                            for (i = 0; i < RawAnalysisProperties.circularListBlockIncrement; i++)
                            {
                                anEvent.next = new RossiAlphaCircularNeutronEvent(i + numObjectsInCircularLinkedList);
                                anEvent      = anEvent.next;
                            }
                            anEvent.next = nextEvent;                                                           //patch the circular linked list back together
                            numObjectsInCircularLinkedList += RawAnalysisProperties.circularListBlockIncrement; //increase the record of the number of structs in the circular list
                        }

                        //move endOfNeutronEventList to the next empty struct
                        endOfList = endOfList.next;

                        //for fun, count how many times we have lapped the circular list in this experiment
                        if (endOfList.serialNumber == 0)
                        {
                            numCircuits++;
                        }

                        //see if oldest event in the queue is expiring,
                        //and while there are expiring events calculate the RossiAlpha statistics for those events
                        deltaTimeInQueue = eventTime - startOfList.eventTime;
                        while (deltaTimeInQueue > rossiAlphaWindowWidth)
                        {
                            //record the time of the expiring gate from the startOfList event, the total measured time for this experiment
                            totalRossiAlphaAnalysisTime = startOfList.eventTime + rossiAlphaWindowWidth;

                            //do RossiAlpha analysis here, accumulating statistics
                            //add up how many neutrons there were in each RossiAlpha gate from the time of the expiring event
                            int    whichBin;
                            UInt64 deltaTime;
                            RossiAlphaCircularNeutronEvent anEvent;

                            //skip the event at the head of the list.
                            //To match data from the legacy code, start with the neutron event following this expiring head event.
                            anEvent = startOfList.next;
                            while (anEvent.serialNumber != endOfList.serialNumber)  //...that is, until we reach the end of the list...
                            {
                                //Find the lowest bin with end time greater than the time of anEvent.
                                deltaTime = anEvent.eventTime - startOfList.eventTime;
                                whichBin  = (int)(Math.Ceiling((double)deltaTime / (double)rossiAlphaGateWidth) + 0.1);

                                if (whichBin < RawAnalysisProperties.numRAGatesPerWindow)  //then this event falls into a bin; add this event's neutrons to that bin
                                {
                                    neutronsPerRossiAlphaGate[whichBin] += anEvent.numNeutrons;
                                    //go to the next event
                                    anEvent = anEvent.next;
                                }
                                else
                                {
                                    anEvent = endOfList;  //abort the loop by going to the end of the list
                                }
                            }

                            //remove expiring oldest event from the stack
                            startOfList = startOfList.next;

                            //re-calculate the delta time in the stack
                            deltaTimeInQueue = eventTime - startOfList.eventTime;
                        } //END of handling an individual NeutronEvent
                    }     //END of handling this block of events

                    //prepare this thread's wait condition so will wait for a message
                    //before telling master thread this thread's analysis is complete
                    waitingForMessage.Reset();
                }  //END of if(keepRunning)
                else
                {
                    //The master thread has cleared the keepRunning flag, so this worker is exiting
                    //Do any cleanup etc. here.
                }
            }  //END of while(keepRunning)
        }