void vmm1Calibration::Loop()
{
  const int verbose = 0;
//   In a ROOT session, you can do:
//      Root > .L vmm1Calibration.C
//      Root > vmm1Calibration t
//      Root > t.GetEntry(12); // Fill t data members with entry number 12
//      Root > t.Show();       // Show values of entry 12
//      Root > t.Show(16);     // Read and show values of entry 16
//      Root > t.Loop();       // Loop on all entries
//

//     This is the loop skeleton where:
//    jentry is the global entry number in the chain
//    ientry is the entry number in the current Tree
//  Note that the argument to GetEntry must be:
//    jentry for TChain::GetEntry
//    ientry for TTree::GetEntry and TBranch::GetEntry
//
//       To read only selected branches, Insert statements like:
// METHOD1:
//    fChain->SetBranchStatus("*",0);  // disable all branches
//    fChain->SetBranchStatus("branchname",1);  // activate branchname
// METHOD2: replace line
//    fChain->GetEntry(jentry);       //read all branches
//by  b_branchname->GetEntry(ientry); //read only this branch
   if (fChain == 0) return;

   const Long64_t nentries = fChain->GetEntriesFast();
   std::cout << "nentries="<<nentries << std::endl;

   // UInt_t          pulser;
   // Double_t        gain;
   // UInt_t          board;
   // vector<double>  *channel;
   // vector<double>  *neighbor;
   // vector<double>  *pdo;
   // vector<double>  *tdo;
   // UInt_t          timeMode;

   const int numChannels = 64;

   int initialPulse=-1;
   int initialGain=-1;
   int initialWaittime=-1;

   int currentPulse=-1;
   int currentGain=-1;
   int currentWaittime=-1;

   int currentChannel=-1;

   // dimensions of these: channel, 
   std::vector< std::vector<float> > vectorOfXvalues(64);
   std::vector< std::vector<float> > vectorOfYvalues(64);
   std::vector< std::vector<float> > vectorOfYerrors(64);

   int nSamples = 0;
   double meanTdo = 0.;
   double meanPdo = 0.;

   // Create vector of TH1F objects, 1 per value of timeMode or pulser, per channel
   //std::vector< std::vector<TH1F*> > myHistos(64)(4);
   //for (channel=0; channel<64; channel++) {
   //  for (xpt=0,xpt<4) {//loop over the number of pulser values (or timeMode values) we have for each channel
   //    myHistos.at(i).at(j) = new TH1F("h_"+ch+"_"j,"h_"+ch+"_"+j,100,0,4000);
   //  }
   //  NOTE: this skeleton is not ideal... number of data points for each channel (4) is hard-coded
   //  Ideally we would create the TH1F instances inside the event loop below,
   //  and so get the number of histograms for each channel from the data
   //  so that if we change to 5 data points per channel, we get 5 histograms
   //  To do this, we could have code inside the event loop that creates a new
   //  new TH1F instance and does myHistos.at(ch).push_back(theNewTH1Finstance) below
   //  whenever we see a new timeMode or pulser value (depending on whether we're in TIMECALIB or GAINCALIB mode)
   //}

   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {
      Long64_t ientry = LoadTree(jentry);
      if (ientry < 0) break;
      nb = fChain->GetEntry(jentry);   nbytes += nb;
      // if (Cut(ientry) < 0) continue;

      if (jentry==0) {
	initialPulse = pulser;
	initialGain = gain;
	initialWaittime = timeMode;

	currentPulse = pulser;
	currentGain = gain;
	currentWaittime = timeMode;
	if (channel->size()>0) {currentChannel = channel->at(0);}

	initialGain = 9;
      }

      if (verbose==3) {
	std::cout << jentry << ": " << pulser << " " << timeMode
		  << ": " << channel->size() << " " << pdo->size() << " " << tdo->size();
	std::cout << "    " << channel->at(0) << " " << pdo->at(0) << " " << tdo->at(0);
	std::cout << std::endl;
      }

      //blah note for pdo:
      //1 lsb = 3.3/16384 (from George Iakovidis 2014/2/28)

      // We should have two modes: time calibration and gain calibration
      // Time calibration: X=pulseWidth(var:currentWaittime), Y=meanTdo
      // Gain calibration: X=pulseSize(var:pulser),           Y=meanPdo

      if (calibMode==TIMECALIB) {
	if ((int)pulser!=initialPulse) {
	  // check that we have the right pulser value, so that we perform
	  // all of the tdoVsWaittime calibration with a single value of pulser
	  continue;
	}
      }

      if (calibMode==GAINCALIB) {
	if ((int)gain!=initialGain || (int)timeMode!=initialWaittime) {
	  //std::cout << " WARNING on gain,timeMode: " << gain << "," << initialGain
	  //	    << ";   " << timeMode << "," << initialWaittime
	  //	    << std::endl;
	  continue;
	}
      }

      if (channel->size()>1) {
	//std::cout << "Ignore event with channel: ";
	//for (unsigned i=0; i<channel->size(); i++) {
	//std::cout << channel->at(i) << ",";
	//}
	//std::cout << std::endl;
	std::cout << "Ignore event with " << channel->size() << " channels" << std::endl;
	continue;
      }

      if (currentPulse==(int)pulser &&
	  (fabs(currentGain-gain)<0.001) &&
	  currentWaittime==(int)timeMode &&
	  ((fabs(currentChannel-channel->at(0)))<0.001) ) {
	// We're still reading all the samples with a single set of fixed values
	//std::cout << "Still on same " << pulser << ", " << gain
	//	  << ", " << timeMode << ", " << channel->at(0) << std::endl;
	nSamples++;
	meanTdo += tdo->at(0);//leakCorrectTdo(tdo->at(0), currentChannel);
	meanPdo += pdo->at(0);//leakCorrectPdo(pdo->at(0), currentChannel);
	// If doing TIMECALIB: Fill value tdo into the TH1F object appropriate for this channel and timeMode value
	//     e.g. myGraphs.at(ch).at(index value of this timeMode value)->Fill(tdo->at(0));
	//     The timeMode index should be 0,1,2,3, corresponding to actual timeMode values of 250,500,750,1000
	//     but ideally the code should be written so that the number of values (4), and the series of values
	//     (250,500,750,1000) are not hard-coded in this file, and instead detected automatically from the data!
	// If doing GAINCALIB: Fill value pdo into the TH1F object appropriate for this channel and pulser value
	if (jentry==nentries-1) {
	  // If this is the last event in the file:
	  meanTdo /= nSamples;
	  meanPdo /= nSamples;
	  std::cout << "=== " << jentry << ": " << nSamples << " samples with "
		    << " pulser="<<currentPulse << " timeMode="<<currentWaittime
		    << " on channel " << currentChannel << std::endl;
	  if (calibMode==TIMECALIB) {
	    if (nSamples>1) {
	      vectorOfXvalues.at(currentChannel).push_back(currentWaittime);
	      vectorOfYvalues.at(currentChannel).push_back(meanTdo *(3.3/16.384));
	      vectorOfYerrors.at(currentChannel).push_back( nSamples>0 ? (meanTdo*(3.3/16.384))/TMath::Sqrt(nSamples) : 0 );
	    }
	  }
	  if (calibMode==GAINCALIB) {
	    if (nSamples>1) {
	      vectorOfXvalues.at(currentChannel).push_back(getChargeFromPulseDAC(currentPulse));
	      vectorOfYvalues.at(currentChannel).push_back(meanPdo *(3.3/16.384));
	      vectorOfYerrors.at(currentChannel).push_back( nSamples>0 ? (meanPdo*(3.3/16.384))/TMath::Sqrt(nSamples) : 0 );
	    }
	  }
	  nSamples = 0;
	  meanTdo = 0.;
	  meanPdo = 0.;
	}
      } else {
	// We enter here if the settings and channel number have changed
	// wrt the previous event
	// First check whether the next event has the same channel etc as this
	if (0) {
	  // If the current event has different channel etc. than previous event
	  // and also different channel than next event, then ignore this event
	  // (assume it's just random noise)
	} else {
	  // We've got to the first event where one of the values changed, so
	  // we should record the data from previous nSamples into plot
	  meanTdo /= nSamples;
	  meanPdo /= nSamples;
	  std::cout << "=== " << jentry << ": " << nSamples << " samples with "
		    << " pulser="<<currentPulse << " timeMode="<<currentWaittime
		    << " on channel " << currentChannel << std::endl;
	  //if (vectorOfXvalues.find(currentWaittime)==vectorOfXvalues.end()) {
	  // if we haven't yet encountered this wait time, need to set up vectors to store the data
	  //Must also do (for n in channels) vectorOfYvalues.at(channel).at(the new currentWaittime).push_back(new vector);
	  //}
	  if (calibMode==TIMECALIB) {
	    if (nSamples>1) {
	      vectorOfXvalues.at(currentChannel).push_back(currentWaittime);
	      vectorOfYvalues.at(currentChannel).push_back(meanTdo *(3.3/16.384));
	      vectorOfYerrors.at(currentChannel).push_back( nSamples>0 ?
							    (meanTdo*(3.3/16.384))/TMath::Sqrt(nSamples) : 0 );
	    }
	  }
	  if (calibMode==GAINCALIB) {
	    if (nSamples>1) {
	      vectorOfXvalues.at(currentChannel).push_back(getChargeFromPulseDAC(currentPulse));
	      vectorOfYvalues.at(currentChannel).push_back(meanPdo *(3.3/16.384));
	      vectorOfYerrors.at(currentChannel).push_back( nSamples>0 ?
							    (meanPdo*(3.3/16.384))/TMath::Sqrt(nSamples) : 0 );
	    }
	  }
	  nSamples = 0;
	  meanTdo = 0.;
	  meanPdo = 0.;
	  // Now we've finished dealing with previous set of values, but still
	  // need to save the data from previous event
	  nSamples++;
	  meanTdo += tdo->at(0);//correctTdo(tdo->at(0), currentChannel);
	  meanPdo += pdo->at(0);//correctPdo(pdo->at(0), currentChannel);
	  // If doing TIMECALIB: Fill value tdo into the TH1F object appropriate for this channel and timeMode value
	  // If doing GAINCALIB: Fill value pdo into the TH1F object appropriate for this channel and pulser value
	}
      }

      currentPulse = pulser;
      currentGain = gain;
      currentWaittime = timeMode;
      currentChannel = channel->at(0);
   }

   std::cout << "Finished looping over events" << std::endl;

   std::cout << "Creating TCanvas" << std::endl;
   TCanvas *c1 = new TCanvas("c1","c1",700,700);
   c1->SetLeftMargin(0.15);
   c1->SetFillColor(kWhite);

   std::cout << "Will now look at histograms TH1Fs to study outliers" << std::endl;
   // Insert code for drawing TH1F objects etc.
   //for (ch=0; ch<10; ch++) {//At least to start, on
   //  for (xpt=0; xpt<myHistos.at(ch).size(); xpt++) {//loop over the number of pulser values (or timeMode values)  we have for each channel
   //    // Draw the TH1F object:
   //    myHistos.at(...).at(...)->Draw("hist");
   //    c1->Print(...);//Exports the plot to a .png or .eps file Look at similar c1->Print(... ) lines below to see how to use
   //    //Ideally save as both png and eps, and make the filename contain the type of calibration (time or gain), and the channel number, and the xpt value
   //  }
   //  NOTE: The above code skeleton is designed to draw a single histogram
   //  at a time, and save each individual histogram to a single file
   //  An alternative here, possibly nicer, is to have a file channel, with
   //  the 4 histograms plotted on top of each other, each different colour
   //  Code would be something like this:
   //  //Make each of the 4 histos different colour:
   //  myHistos.at(ch).at(0)->SetLineColor(getMyColor(0));
   //  myHistos.at(ch).at(0)->SetMarkerColor(getMyColor(0));
   //  myHistos.at(ch).at(1)->SetLineColor(getMyColor(1));
   //  myHistos.at(ch).at(1)->SetMarkerColor(getMyColor(1));
   //  myHistos.at(ch).at(2)->SetLineColor(getMyColor(2));
   //  myHistos.at(ch).at(2)->SetMarkerColor(getMyColor(2));
   //  myHistos.at(ch).at(3)->SetLineColor(getMyColor(3));
   //  myHistos.at(ch).at(3)->SetMarkerColor(getMyColor(3));
   //  // Now draw the 4 histos
   //  myHistos.at(ch).at(0)->Draw("hist");
   //  myHistos.at(ch).at(1)->Draw("hist same");// string "same" means overlay on existing axes
   //  myHistos.at(ch).at(2)->Draw("hist same");
   //  myHistos.at(ch).at(3)->Draw("hist same");// change so that we loop over 0,1,2,3,
   //                               //without hard-coding the number of histograms per channel!
   //  c1->Print(...);
   //}

   std::cout << "Will now create TGraphs" << std::endl;
   std::vector<TGraph*> myGraphs;
   for (int ch=0; ch<numChannels; ch++) {myGraphs.push_back(0);}
   
   for (int ch=0; ch<numChannels; ch++) {
     const unsigned nPoints = vectorOfXvalues.at(ch).size();
     if (nPoints!=vectorOfYvalues.at(ch).size()) {std::cout<<"Error with vector sizes"<<std::endl;return;}
     if (nPoints>0) {
       int xtmp[nPoints];
       int ytmp[nPoints];
       for (unsigned i=0; i<nPoints; i++) {xtmp[i]=vectorOfXvalues.at(ch).at(i); ytmp[i]=vectorOfYvalues.at(ch).at(i);}
       TGraph *g = new TGraph( nPoints, xtmp, ytmp );
       g->SetName(Form("graph_ch%i",ch));
       myGraphs.at(ch) = g;
       //std::cout << "Created TGraph for ch="<<ch << std::endl;
     }
   }

   // Set up aesthetic options for the graphs
   TLegend *myleg1 = new TLegend(0.20,0.49,0.33,0.94);
   TLegend *myleg2 = new TLegend(0.33,0.64,0.46,0.94);
   TLegend *myleg3 = new TLegend(0.46,0.79,0.59,0.94);
   myleg1->SetFillColor(kWhite);
   myleg1->SetBorderSize(1);
   myleg2->SetFillColor(kWhite);
   myleg2->SetBorderSize(1);
   myleg3->SetFillColor(kWhite);
   myleg3->SetBorderSize(1);
   for (int ch=0; ch<numChannels; ch++) {
     if (myGraphs.at(ch)) {
       // Use markers 20-27
       myGraphs.at(ch)->SetMarkerStyle(20 + ch%8);
       myGraphs.at(ch)->SetMarkerColor(getMyColor(ch));
       myGraphs.at(ch)->SetLineColor(kWhite);
       myGraphs.at(ch)->SetFillColor(kWhite);
       myGraphs.at(ch)->SetLineWidth(0);
       //std::cout << "GetMarkerSize:  " << myGraphs.at(ch)->GetMarkerSize() << std::endl;
       myGraphs.at(ch)->SetMarkerSize(1.2);
       if (ch<32) {
	 myleg1->AddEntry(myGraphs.at(ch),Form("Channel %i",ch));
       } else if (ch<53) {
	 myleg2->AddEntry(myGraphs.at(ch),Form("Channel %i",ch));
       } else {
	 myleg3->AddEntry(myGraphs.at(ch),Form("Channel %i",ch));
       }
     }
   }
   
   //std::cout << "Creating TCanvas" << std::endl;
   //TCanvas *c1 = new TCanvas("c1","c1",700,700);
   //c1->SetLeftMargin(0.15);
   //c1->SetFillColor(kWhite);
   if (!myGraphs.at(0)) {std::cout << "ERROR: myGraphs.at(0) is empty!!!" << std::endl;}
   // Find first non-NULL member of myGraphs
   int firstNonNullGraph = 0;
   for (int ch=0; ch<numChannels; ch++) {
     if (myGraphs.at(ch)) {
       firstNonNullGraph = ch;
       break;
     }
   }

   for (int ch=firstNonNullGraph; ch<numChannels; ch++) {
     if (!myGraphs.at(ch)) continue;
     myGraphs.at(ch)->SetTitle(0);
     myGraphs.at(ch)->SetMinimum(0);//y
     myGraphs.at(ch)->SetMaximum(1500.);//7000);//4000);//y
     if (calibMode==GAINCALIB) {
       myGraphs.at(ch)->GetXaxis()->SetLimits(0,100);//500);//x
       myGraphs.at(ch)->GetXaxis()->SetTitle("Induced charge from pulse (fC)");
       myGraphs.at(ch)->GetYaxis()->SetTitle("Mean PDO (mV)");
     } else if (calibMode==TIMECALIB) {
       myGraphs.at(ch)->GetXaxis()->SetLimits(0,1200);//500);//x
       myGraphs.at(ch)->GetXaxis()->SetTitle("Wait time (ns)");
       myGraphs.at(ch)->GetYaxis()->SetTitle("Mean TDO (mV)");
     }
     myGraphs.at(ch)->GetYaxis()->SetTitleOffset(1.7);
   }

   myGraphs.at(firstNonNullGraph)->Draw("AP");
   for (int ch=firstNonNullGraph+1; ch<numChannels; ch++) {
     if (myGraphs.at(ch)) myGraphs.at(ch)->Draw("P");
   }
   myleg1->Draw();
   myleg2->Draw();
   myleg3->Draw();
   c1->Print(Form("calib%s.png",(calibMode==GAINCALIB ? "Gain" : "Time")));
   c1->Print(Form("calib%s.eps",(calibMode==GAINCALIB ? "Gain" : "Time")));

   // Now fit the graphs!
   for (int ch=0; ch<numChannels; ch++) {
     if (vectorOfYvalues.at(ch).size()>1) {
       if (myGraphs.at(ch)) {
	 myGraphs.at(ch)->Fit("pol1","Q");
	 TF1 *myfit = myGraphs.at(ch)->GetFunction("pol1");
	 printf("Fitted channel %2i => p0=%5.0f, p1=%6.3f using %i points\n",
		ch, myfit->GetParameter(0), myfit->GetParameter(1),
		(int)vectorOfYvalues.at(ch).size());
	 myfit->SetLineColor(getMyColor(ch));
	 myfit->SetLineWidth(1);
       }
     }
   }
   c1->Print(Form("calib%sWithFits.png",(calibMode==GAINCALIB ? "Gain" : "Time")));
   c1->Print(Form("calib%sWithFits.eps",(calibMode==GAINCALIB ? "Gain" : "Time")));

   for (int ch=0; ch<numChannels; ch++) {
     if (!myGraphs.at(ch)) continue;
     myGraphs.at(ch)->Draw("AP");
     TF1 *myfit = myGraphs.at(ch)->GetFunction("pol1");
     //if (ch<32)        {myleg1->Draw();
     //} else if (ch<53) {myleg2->Draw();
     //} else            {myleg3->Draw();}
     TPaveText *t = new TPaveText(0.2,0.8,0.5,0.9,"NDC");
     t->AddText(Form("Channel %i with %i data points",
		     ch,(int)vectorOfYvalues.at(ch).size()));
     if (myfit) t->AddText(Form(" Fit params: p0=%5.0f, p1=%6.3f",
				myfit->GetParameter(0), myfit->GetParameter(1)));
     t->SetFillColor(kWhite);
     t->SetBorderSize(1);
     t->Draw();
     c1->Print(Form("calib%s_ch%02i.png",(calibMode==GAINCALIB ? "Gain" : "Time"),ch));
     c1->Print(Form("calib%s_ch%02i.eps",(calibMode==GAINCALIB ? "Gain" : "Time"),ch));
   }
}
Ejemplo n.º 2
0
/****************************************************************************
 Function
    RunSendBytesStatus

 Parameters
   ES_Event: the event to process

 Returns
   ES_Event: an event to return

 Description
   add your description here
 Notes
   uses nested switch/case to implement the machine.
 Author
   J. Edward Carryer, 2/11/05, 10:45AM
****************************************************************************/
ES_Event RunSendBytesStatus( ES_Event CurrentEvent )
{
   bool MakeTransition = false;/* are we making a state transition? */
   SendBytesState_t NextState = CurrentState;
   ES_Event EntryEventKind = { ES_ENTRY, 0 };// default to normal entry to new state
   ES_Event ReturnEvent = CurrentEvent; // assume we are not consuming event

   switch ( CurrentState )
   {
       case WAITING_SENDBYTES :       // If current state is WAITING
         // Execute During function for WAITING. ES_ENTRY & ES_EXIT are
         // processed here allow the lower level state machines to re-map
         // or consume the event
         CurrentEvent = DuringWaiting(CurrentEvent);
         //process any events
         if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
         {
            switch (CurrentEvent.EventType)
            {
               case RETURN_STATUS : //If event is RETURN_STATUS
                  // Execute action function for state one : event one
                  NextState = SENDING_SENDBYTES;//Decide what the next state will be
                  // for internal transitions, skip changing MakeTransition
                  MakeTransition = true; //mark that we are taking a transition
                  // if transitioning to a state with history change kind of entry
                  EntryEventKind.EventType = ES_ENTRY;
                  // optionally, consume or re-map this event for the upper
                  // level state machine
                  ReturnEvent.EventType = ES_NO_EVENT;
							 
									//This is a status request
									isStatus = true;
							 
									PostStatusPAC(CurrentEvent);
                  break;
							 
							 case RETURN_REQUEST : //If event is RETURN_STATUS
                  // Execute action function for state one : event one
                  NextState = SENDING_SENDBYTES;//Decide what the next state will be
                  // for internal transitions, skip changing MakeTransition
                  MakeTransition = true; //mark that we are taking a transition
                  // if transitioning to a state with history change kind of entry
                  EntryEventKind.EventType = ES_ENTRY;
                  // optionally, consume or re-map this event for the upper
                  // level state machine
                  ReturnEvent.EventType = ES_NO_EVENT;
							 
							 
									PostStatusPAC(CurrentEvent);
                  break;
							 
							 case RETURN_QUERY : //If event is RETURN_STATUS
                  // Execute action function for state one : event one
                  NextState = SENDING_SENDBYTES;//Decide what the next state will be
                  // for internal transitions, skip changing MakeTransition
                  MakeTransition = true; //mark that we are taking a transition
                  // if transitioning to a state with history change kind of entry
                  EntryEventKind.EventType = ES_ENTRY;
                  // optionally, consume or re-map this event for the upper
                  // level state machine
                  ReturnEvent.EventType = ES_NO_EVENT;
							 
							 
									PostStatusPAC(CurrentEvent);
                  break;
                             case RETURN_PSEUDO_QUERY : //If event is RETURN_STATUS
                  // Execute action function for state one : event one
                  NextState = SENDING_SENDBYTES;//Decide what the next state will be
                  // for internal transitions, skip changing MakeTransition
                  MakeTransition = true; //mark that we are taking a transition
                  // if transitioning to a state with history change kind of entry
                  EntryEventKind.EventType = ES_ENTRY;
                  // optionally, consume or re-map this event for the upper
                  // level state machine
                  ReturnEvent.EventType = ES_NO_EVENT;
							 
                                    isPseudo = true;
									PostStatusPAC(CurrentEvent);
                  break;    

            }
         }
         break;

	   case SENDING_SENDBYTES:       // If current state is SENDING
         // Execute During function for SENDING. ES_ENTRY & ES_EXIT are
         // processed here allow the lower level state machines to re-map
         // or consume the event
         CurrentEvent = DuringSending(CurrentEvent);
					uint8_t freqCode;
         //process any events
         if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
         {
            switch (CurrentEvent.EventType)
            {
               case RETURN_STATUS : //If event is GET_STATUS
								 
									#ifdef DEBUG_SENDBYTES
									printf("\rSending status\r\n");
									#endif
								 
									for (uint8_t i = 0; i < 5; i++)
									{
										WriteFIFO(getStatus[i]);
										#ifdef DEBUG_SENDBYTES
									  printf("%x\r\n",getStatus[i]);
										#endif
									}

									//Enable the NVIC interrupt for the SSI when starting to transmit (or receive?)
									HWREG(NVIC_BASE+EN0) |= BIT7HI; //Interrupt 7 for SSI0

                  // Execute action function for state one : event one
                  NextState = WAITING4EOT;//Decide what the next state will be
                  // for internal transitions, skip changing MakeTransition
                  MakeTransition = true; //mark that we are taking a transition
                  // if transitioning to a state with history change kind of entry
                  EntryEventKind.EventType = ES_ENTRY;
                  // optionally, consume or re-map this event for the upper
                  // level state machine
                  ReturnEvent.EventType = ES_NO_EVENT;
                  break;
							 
							 case RETURN_REQUEST : //If event is GET_STATUS
								 
									freqCode = (uint8_t)CurrentEvent.EventParam;
									uint8_t myColor = getMyColor();
									uint8_t colorCode = ((myColor << 4) | (myColor << 5));
									getRequest[0] = 0x80 | freqCode | colorCode;
							 
									#ifdef DEBUG_SENDBYTES
									printf("\rCurrent Request\r\n");
									#endif
									for (uint8_t i = 0; i < 5; i++)
									{
										WriteFIFO(getRequest[i]);
										#ifdef DEBUG_SENDBYTES
										printf("%x\r\n",getRequest[i]);
										#endif
									}
									//Enable the NVIC interrupt for the SSI when starting to transmit (or receive?)
									HWREG(NVIC_BASE+EN0) |= BIT7HI; //Interrupt 7 for SSI0
                  // Execute action function for state one : event one
                  NextState = WAITING4EOT;//Decide what the next state will be
                  // for internal transitions, skip changing MakeTransition
                  MakeTransition = true; //mark that we are taking a transition
                  // if transitioning to a state with history change kind of entry
                  EntryEventKind.EventType = ES_ENTRY;
                  // optionally, consume or re-map this event for the upper
                  // level state machine
                  ReturnEvent.EventType = ES_NO_EVENT;
                  break;
							 
							 case RETURN_QUERY : //If event is GET_STATUS
								 
									#ifdef DEBUG_SENDBYTES
									printf("\rSending\r\n");
									#endif
									for (uint8_t i = 0; i < 5; i++)
									{
										WriteFIFO(getQuery[i]);
										#ifdef DEBUG_SENDBYTES
									  printf("%x\r\n",getQuery[i]);
										#endif
									}
									//Enable the NVIC interrupt for the SSI when starting to transmit (or receive?)
									HWREG(NVIC_BASE+EN0) |= BIT7HI; //Interrupt 7 for SSI0
                  // Execute action function for state one : event one
                  NextState = WAITING4EOT;//Decide what the next state will be
                  // for internal transitions, skip changing MakeTransition
                  MakeTransition = true; //mark that we are taking a transition
                  // if transitioning to a state with history change kind of entry
                  EntryEventKind.EventType = ES_ENTRY;
                  // optionally, consume or re-map this event for the upper
                  // level state machine
                  ReturnEvent.EventType = ES_NO_EVENT;
                  break;
                            
                                case RETURN_PSEUDO_QUERY : //If event is GET_STATUS
								 
									#ifdef DEBUG_SENDBYTES
									printf("\rSending\r\n");
									#endif
									for (uint8_t i = 0; i < 5; i++)
									{
										WriteFIFO(getQuery[i]);
										#ifdef DEBUG_SENDBYTES
									  printf("%x\r\n",getQuery[i]);
										#endif
									}
									//Enable the NVIC interrupt for the SSI when starting to transmit (or receive?)
									HWREG(NVIC_BASE+EN0) |= BIT7HI; //Interrupt 7 for SSI0
                  // Execute action function for state one : event one
                  NextState = WAITING4EOT;//Decide what the next state will be
                  // for internal transitions, skip changing MakeTransition
                  MakeTransition = true; //mark that we are taking a transition
                  // if transitioning to a state with history change kind of entry
                  EntryEventKind.EventType = ES_ENTRY;
                  // optionally, consume or re-map this event for the upper
                  // level state machine
                  ReturnEvent.EventType = ES_NO_EVENT;
                  break;
                              
            }
         }
         break;
		 
	   case WAITING4EOT :       // If current state is WAITING4EOT
         // Execute During function for SENDING. ES_ENTRY & ES_EXIT are
         // processed here allow the lower level state machines to re-map
         // or consume the event
         CurrentEvent = DuringWaiting4EOT(CurrentEvent);
         //process any events
         if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
         {
            switch (CurrentEvent.EventType)
            {
               case EOT_TIMEOUT : //If event is GET_STATUS
								#ifdef DEBUG_SENDBYTES
								if(!isStatus)
									{printf("\rReading result\r\n");
									}
									#endif
									for (uint8_t i = 0; i < 5; i++)
									{
										readdata[i] = ReadFIFO();
										#ifdef DEBUG_SENDBYTES
										if(!isStatus){printf("\r%x\r\n",readdata[i]);}
										#endif
									}
								
                  // Execute action function for state one : event one
                  NextState = WAITING4TIMEOUT;//Decide what the next state will be
                  // for internal transitions, skip changing MakeTransition
                  MakeTransition = true; //mark that we are taking a transition
                  // if transitioning to a state with history change kind of entry
                  EntryEventKind.EventType = ES_ENTRY;
                  // optionally, consume or re-map this event for the upper
                  // level state machine
                  ReturnEvent.EventType = ES_NO_EVENT;
									ES_Timer_InitTimer(EOTTimer,2);
                  break;
            }
         }
         break;
		 
	   case WAITING4TIMEOUT :       // If current state is WAITING4TIMEOUT
         // Execute During function for SENDING. ES_ENTRY & ES_EXIT are
         // processed here allow the lower level state machines to re-map
         // or consume the event
         CurrentEvent = DuringWaiting4Timeout(CurrentEvent);
         //process any events
         if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
         {
            switch (CurrentEvent.EventType)
            {   
							case ES_TIMEOUT:
								// Execute action function for state one : event one
								NextState =  WAITING_SENDBYTES;//Decide what the next state will be
								// for internal transitions, skip changing MakeTransition
								MakeTransition = true; //mark that we are taking a transition
								// if transitioning to a state with history change kind of entry
								EntryEventKind.EventType = ES_ENTRY;
								// optionally, consume or re-map this event for the upper
								// level state machine
								ES_Event CompletedEvent;
							
								
								CompletedEvent.EventType = PAC_COMM_COMPLETE;
								
								for (uint8_t i= 0; i < 5; i++)
								{
									CompletedEvent.EventArray[i] = readdata[i];
								}
								
								//If this is a status request, send back to only Strategy
								//Otherwise, send to only campaigning
								if(isStatus)
								{

									PostStrategySM(CompletedEvent);
									
									isStatus = false;
								}
                                else if(isPseudo)
								{
									isPseudo = false;
								}
								else
								{
									//return or query request returned to 
									//campagin

									PostCampaigningSM(CompletedEvent);
									
								}
			
								break;
							}
         }
         break;
      // repeat state pattern as required for other states
    }
    //   If we are making a state transition
    if (MakeTransition == true)
    {
       //   Execute exit function for current state
       CurrentEvent.EventType = ES_EXIT;
       RunSendBytesStatus(CurrentEvent);

       CurrentState = NextState; //Modify state variable

       //   Execute entry function for new state
       // this defaults to ES_ENTRY
       RunSendBytesStatus(EntryEventKind);
     }
     return(ReturnEvent);
}