예제 #1
0
파일: Game.cpp 프로젝트: mafiamole/MoleBox
	int Game::Run()
	{
		EventList eventList;
		this->window->setFramerateLimit(60);
		//clock.restart();
		sf::Time elapsed = clock.restart();

		while ( this->window->isOpen() )
		{

			sf::Event event;

			while ( window->pollEvent(event) )
			{
				if ( event.type == sf::Event::Closed )
					window->close();
	//       else if ( event.type = sf::Event::Resized )
	// 	this->windowResized = true;
			else
			  eventList.insert( std::pair< sf::Event::EventType,sf::Event >( event.type,event ) );

		}

			window->clear();

			this->Update( elapsed , &eventList );

			this->Draw();

			this->window->display();

			eventList.clear();

			elapsed = clock.restart();

		}


		return 0;
	}
void ConvertToDiffractionMDWorkspace::convertEventList(int workspaceIndex,
                                                       EventList &el) {
  size_t numEvents = el.getNumberEvents();
  DataObjects::MDBoxBase<DataObjects::MDLeanEvent<3>, 3> *box = ws->getBox();

  // Get the position of the detector there.
  const std::set<detid_t> &detectors = el.getDetectorIDs();
  if (!detectors.empty()) {
    // Get the detector (might be a detectorGroup for multiple detectors)
    // or might return an exception if the detector is not in the instrument
    // definition
    IDetector_const_sptr det;
    try {
      det = m_inWS->getDetector(workspaceIndex);
    } catch (Exception::NotFoundError &) {
      this->failedDetectorLookupCount++;
      return;
    }

    // Vector between the sample and the detector
    V3D detPos = det->getPos() - samplePos;

    // Neutron's total travelled distance
    double distance = detPos.norm() + l1;

    // Detector direction normalized to 1
    V3D detDir = detPos / detPos.norm();

    // The direction of momentum transfer in the inelastic convention ki-kf
    //  = input beam direction (normalized to 1) - output beam direction
    //  (normalized to 1)
    V3D Q_dir_lab_frame = beamDir - detDir;
    double qSign = -1.0;
    std::string convention =
        ConfigService::Instance().getString("Q.convention");
    if (convention == "Crystallography")
      qSign = 1.0;
    Q_dir_lab_frame *= qSign;

    // Multiply by the rotation matrix to convert to Q in the sample frame (take
    // out goniometer rotation)
    // (or to HKL, if that's what the matrix is)
    V3D Q_dir = mat * Q_dir_lab_frame;

    // For speed we extract the components.
    coord_t Q_dir_x = coord_t(Q_dir.X());
    coord_t Q_dir_y = coord_t(Q_dir.Y());
    coord_t Q_dir_z = coord_t(Q_dir.Z());

    // For lorentz correction, calculate  sin(theta))^2
    double sin_theta_squared = 0;
    if (LorentzCorrection) {
      // Scattering angle = 2 theta = angle between neutron beam direction and
      // the detector (scattering) direction
      // The formula for Lorentz Correction is sin(theta), i.e. sin(half the
      // scattering angle)
      double theta = detDir.angle(beamDir) / 2.0;
      sin_theta_squared = sin(theta);
      sin_theta_squared = sin_theta_squared * sin_theta_squared; // square it
    }

    /** Constant that you divide by tof (in usec) to get wavenumber in ang^-1 :
     * Wavenumber (in ang^-1) =  (PhysicalConstants::NeutronMass * distance) /
     * ((tof (in usec) * 1e-6) * PhysicalConstants::h_bar) * 1e-10; */
    const double wavenumber_in_angstrom_times_tof_in_microsec =
        (PhysicalConstants::NeutronMass * distance * 1e-10) /
        (1e-6 * PhysicalConstants::h_bar);

    // PARALLEL_CRITICAL( convert_tester_output ) { std::cout << "Spectrum " <<
    // el.getSpectrumNo() << " beamDir = " << beamDir << " detDir = " << detDir
    // << " Q_dir = " << Q_dir << " conversion factor " <<
    // wavenumber_in_angstrom_times_tof_in_microsec << std::endl;  }

    // g_log.information() << wi << " : " << el.getNumberEvents() << " events.
    // Pos is " << detPos << std::endl;
    // g_log.information() << Q_dir.norm() << " Qdir norm" << std::endl;

    // This little dance makes the getting vector of events more general (since
    // you can't overload by return type).
    typename std::vector<T> *events_ptr;
    getEventsFrom(el, events_ptr);
    typename std::vector<T> &events = *events_ptr;

    // Iterators to start/end
    auto it = events.begin();
    auto it_end = events.end();

    for (; it != it_end; it++) {
      // Get the wavenumber in ang^-1 using the previously calculated constant.
      coord_t wavenumber =
          coord_t(wavenumber_in_angstrom_times_tof_in_microsec / it->tof());

      // Q vector = K_final - K_initial = wavenumber * (output_direction -
      // input_direction)
      coord_t center[3] = {Q_dir_x * wavenumber, Q_dir_y * wavenumber,
                           Q_dir_z * wavenumber};

      // Check that the event is within bounds
      if (center[0] < m_extentsMin[0] || center[0] >= m_extentsMax[0])
        continue;
      if (center[1] < m_extentsMin[1] || center[1] >= m_extentsMax[1])
        continue;
      if (center[2] < m_extentsMin[2] || center[2] >= m_extentsMax[2])
        continue;

      if (LorentzCorrection) {
        // double lambda = 1.0/wavenumber;
        // (sin(theta))^2 / wavelength^4
        float correct = float(sin_theta_squared * wavenumber * wavenumber *
                              wavenumber * wavenumber);
        // Push the MDLeanEvent but correct the weight.
        box->addEvent(MDE(float(it->weight() * correct),
                          float(it->errorSquared() * correct * correct),
                          center));
      } else {
        // Push the MDLeanEvent with the same weight
        box->addEvent(
            MDE(float(it->weight()), float(it->errorSquared()), center));
      }
    }

    // Clear out the EventList to save memory
    if (ClearInputWorkspace) {
      // Track how much memory you cleared
      size_t memoryCleared = el.getMemorySize();
      // Clear it now
      el.clear();
      // For Linux with tcmalloc, make sure memory goes back, if you've cleared
      // 200 Megs
      MemoryManager::Instance().releaseFreeMemoryIfAccumulated(
          memoryCleared, static_cast<size_t>(2e8));
    }
  }
  prog->reportIncrement(numEvents, "Adding Events");
}
예제 #3
0
int main()
{
    using namespace std;
    EventList Elist;                // Create event list
    enum {ARR,DEP1,DEP2,DEP3,TRANSFER11,TRANSFER13,TRANSFER23,TRANSFER32,TDEP1,TDEP2,TDEP3};                 // Define the event types
    enum{Q1,Q2,Q3};
    
    double lambda=1;            // Arrival rate
    double mu1 = 6.0;
    double mu2 = 25.0;
    double mu3 = 30.0;
    
        exp_rv(lambda);
    double rs1 = (double)1/4;
    double rs2 = (double)3/4;
    double r11 = (double)1/2,r13 = (double)1/2,r3d = (double)2/5,r32 =(double)3/5;
    
    int N = 0;                      // Number of customers in system
    int Ndep = 0;                   // Number of departures from system
    
                      // End condition satisfied?
    
    Event* CurrentEvent;
    
    
    for(lambda = 1; lambda <= 10 ; lambda++ )
    {
        
        int n1 = 0;
        int n2=0;
        int n3=0;
        int tn1 = 0;
        int tn2=0;
        int tn3=0;
        
        int qe1=0,qe2=0,qe3=0; //to keep total entering each queue. for throughput calculation
        double util1=0,util2=0,util3=0, rho1=0, rho2=0, rho3=0;
        
        if(randomGenerator() <= rs1)
            Elist.insert(exp_rv(lambda),ARR,Q1);
        else
            Elist.insert(exp_rv(lambda),ARR,Q2);

        double clock = 0.0;             // System clock
        Ndep = 0;
        double EN1 = 0.0, EN2 = 0.0, EN3 = 0.0;
        int done = 0;
        while (!done)
        {
            CurrentEvent = Elist.get();
            double prev = clock;
            clock=CurrentEvent->time;
            EN1 += (double)((n1+tn1)*(clock-prev));
            EN2 += (double)((n2+tn2)*(clock-prev));
            EN3 += (double)((n3+tn3)*(clock-prev));
            
            if((n1+tn1)>0)
            util1+=(clock-prev);
            if((n2+tn2)>0)
            util2+=(clock-prev);
            if((n3+tn3)>0)
            util3+=(clock-prev);
            
            
            switch (CurrentEvent->type)
            {
            case ARR:
                if(CurrentEvent->queue == 0)
                {
                    n1++;
                    qe1++;
                    //generate next arrival
                    if(randomGenerator() <= rs1)
                        Elist.insert(clock+exp_rv(lambda),ARR, Q1);
                    else
                        Elist.insert(clock+exp_rv(lambda),ARR, Q2);
                
                    if (n1==1)
                    {
                        Elist.insert(clock+exp_rv(mu1),DEP1, Q1);
                    }
                }
                else if(CurrentEvent->queue == 1)
                {
                    n2++;
                    qe2++;
                    //generate next arrival
                    if(randomGenerator() <= rs1)
                        Elist.insert(clock+exp_rv(lambda),ARR, Q1);
                    else
                        Elist.insert(clock+exp_rv(lambda),ARR, Q2);
                    
                    if (n2==1)
                    {
                        Elist.insert(clock+exp_rv(mu2),DEP2, Q2);
                    }
                }
                
                break;
                
                case DEP2:
                n2--;
                if (n2 > 0)
                {
                    Elist.insert(clock+exp_rv(mu2),DEP2,Q2);
                }
                
                Elist.insert(clock+exp_rv(mu2),TRANSFER23, Q3);
                break;
                
                
                case TRANSFER11:
                    tn1++;
                    qe1++;
                    if(tn1>0)
                    {
                        //Generate TDEP for this transfer event
                        Elist.insert(clock+exp_rv(mu1), TDEP1, Q1);
                    }
                    break;
                
                    
                case TDEP1:
                    tn1--;
                    if(randomGenerator()<=r11)
                    {
                    //Its going back to the same queue. Don't generate new arrival event. generate transfer event
                        Elist.insert(clock+exp_rv(mu1),TRANSFER11,Q1);
                    }
                    else
                    {
                        Elist.insert(clock+exp_rv(mu1),TRANSFER13,Q3);
                    
                    }
                break;
                
                    
                case TRANSFER13:
                    tn3++;
                    qe3++;
                    if(tn3>0)
                    {
                        //Generate TDEP for this transfer event
                        Elist.insert(clock+exp_rv(mu3), TDEP3, Q3);
                    }
                    break;
                    
                case TDEP3:
                    tn3--;
                    if(randomGenerator()<=r3d)
                    {
                        //Exits the system
                        Ndep++;
                    }
                    else
                    {
                        Elist.insert(clock+exp_rv(mu3),TRANSFER32,Q2);
                    }
                    break;
                
                case TRANSFER23:
                    tn3++;
                    qe3++;
                    if(tn3>0)
                    {
                        //Generate TDEP for this transfer event
                        Elist.insert(clock+exp_rv(mu3), TDEP3, Q3);
                    }
                    break;
                    
                    
                case TRANSFER32:
                    tn2++;
                    qe2++;
                    if(tn2>0)
                    {
                        //Generate TDEP for this transfer event
                        Elist.insert(clock+exp_rv(mu2), TDEP2, Q2);
                    }
                    break;
                    
                case TDEP2:
                    tn2--;
                    Elist.insert(clock+exp_rv(mu2),TRANSFER23, Q3);
                    break;
                
                case DEP1:
                    n1--;
                    if (n1 > 0)
                    {
                        Elist.insert(clock+exp_rv(mu1),DEP1,Q1);
                    }
                
                    
                    if(randomGenerator()<=r11)
                    {
                    //Its going back to the same queue. Don't generate new arrival event. generate transfer event
                        Elist.insert(clock+exp_rv(mu1),TRANSFER11,Q1);
                    
                    }
                    else
                    {
                        Elist.insert(clock+exp_rv(mu1),TRANSFER13,Q3);
                    }
                    break;
                
                }
            
            EN1=(double)(((qe1/clock)/mu1)/(1-((qe1/clock)/mu1)))*clock; EN2 = (double)(((qe2/clock)/mu2)/(1-((qe2/clock)/mu2)))*clock; EN3=(double)(((qe3/clock)/mu3)/(1-((qe3/clock)/mu3)))*clock;
            //cout<<CurrentEvent->type<<endl;
            //cout<<"N1 : "<<n1+tn1<<"    N2 : "<<n2+tn2<<"    N3 : "<<n3+tn3<<"    Ndep : "<<Ndep<<endl;
            
        delete CurrentEvent;
        if (Ndep > 500000) done=1;        // End condition
    }
        
        
        
        /*Printing Output for each iteration */
        
        
        
        rho1=(double)(qe1/clock)/mu1;
        rho2=(double)(qe2/clock)/mu2;
        rho3=(double)(qe3/clock)/mu3;
        cout<<"Lambda "<<lambda<<endl;
        cout<<"TP1 : "<<qe1/clock<<"    TP2 : "<<qe2/clock<<"    TP3 : "<<qe3/clock<<endl;
        cout<<"Util1 : "<<(rho1)<<"    Util2 : "<<rho2<<"    Util3 : "<<rho3<<endl;
        cout<<"EN1 : "<<EN1/clock<<"    EN2 : "<<EN2/clock<<"    EN3 : "<<EN3/clock<<endl;
        cout<<"E[T1] : "<<(double)(EN1/qe1)<<"    E[T2] : "<<(double)(EN2/qe2)<<"    E[T3] : "<<(double)(EN3/qe3)<<endl;
        
        cout<<endl<<endl;
        
        Elist.clear();
        
}
    
}
void ConvertToDiffractionMDWorkspace::convertEventList(
    int workspaceIndex, const API::SpectrumInfo &specInfo, EventList &el) {
  size_t numEvents = el.getNumberEvents();
  DataObjects::MDBoxBase<DataObjects::MDLeanEvent<3>, 3> *box = ws->getBox();

  // Get the position of the detector there.
  const auto &detectors = el.getDetectorIDs();
  if (!detectors.empty()) {
    // Check if a detector is located at this workspace index, returns
    // immediately if one is not found.
    if (!specInfo.hasDetectors(workspaceIndex)) {
      this->failedDetectorLookupCount++;
      return;
    }

    // Neutron's total travelled distance
    double distance = l1 + specInfo.l2(workspaceIndex);

    // Vector between the sample and the detector
    const V3D detPos = specInfo.position(workspaceIndex);

    // Detector direction normalized to 1
    const V3D detDir = detPos / detPos.norm();

    // The direction of momentum transfer in the inelastic convention ki-kf
    //  = input beam direction (normalized to 1) - output beam direction
    //  (normalized to 1)
    V3D Q_dir_lab_frame = beamDir - detDir;
    double qSign = -1.0;
    std::string convention =
        ConfigService::Instance().getString("Q.convention");
    if (convention == "Crystallography")
      qSign = 1.0;
    Q_dir_lab_frame *= qSign;

    // Multiply by the rotation matrix to convert to Q in the sample frame (take
    // out goniometer rotation)
    // (or to HKL, if that's what the matrix is)
    const V3D Q_dir = mat * Q_dir_lab_frame;

    // For speed we extract the components.
    coord_t Q_dir_x = coord_t(Q_dir.X());
    coord_t Q_dir_y = coord_t(Q_dir.Y());
    coord_t Q_dir_z = coord_t(Q_dir.Z());

    // For lorentz correction, calculate  sin(theta))^2
    double sin_theta_squared = 0;
    if (LorentzCorrection) {
      // Scattering angle = 2 theta = angle between neutron beam direction and
      // the detector (scattering) direction
      // The formula for Lorentz Correction is sin(theta), i.e. sin(half the
      // scattering angle)
      double theta = specInfo.twoTheta(workspaceIndex) / 2.0;
      sin_theta_squared = sin(theta);
      sin_theta_squared = sin_theta_squared * sin_theta_squared; // square it
    }

    /** Constant that you divide by tof (in usec) to get wavenumber in ang^-1 :
     * Wavenumber (in ang^-1) =  (PhysicalConstants::NeutronMass * distance) /
     * ((tof (in usec) * 1e-6) * PhysicalConstants::h_bar) * 1e-10; */
    const double wavenumber_in_angstrom_times_tof_in_microsec =
        (PhysicalConstants::NeutronMass * distance * 1e-10) /
        (1e-6 * PhysicalConstants::h_bar);

    // This little dance makes the getting vector of events more general (since
    // you can't overload by return type).
    typename std::vector<T> *events_ptr;
    getEventsFrom(el, events_ptr);
    typename std::vector<T> &events = *events_ptr;

    // Iterators to start/end
    auto it = events.begin();
    auto it_end = events.end();

    for (; it != it_end; it++) {
      // Get the wavenumber in ang^-1 using the previously calculated constant.
      coord_t wavenumber =
          coord_t(wavenumber_in_angstrom_times_tof_in_microsec / it->tof());

      // Q vector = K_final - K_initial = wavenumber * (output_direction -
      // input_direction)
      coord_t center[3] = {Q_dir_x * wavenumber, Q_dir_y * wavenumber,
                           Q_dir_z * wavenumber};

      // Check that the event is within bounds
      if (center[0] < m_extentsMin[0] || center[0] >= m_extentsMax[0])
        continue;
      if (center[1] < m_extentsMin[1] || center[1] >= m_extentsMax[1])
        continue;
      if (center[2] < m_extentsMin[2] || center[2] >= m_extentsMax[2])
        continue;

      if (LorentzCorrection) {
        // double lambda = 1.0/wavenumber;
        // (sin(theta))^2 / wavelength^4
        float correct = float(sin_theta_squared * wavenumber * wavenumber *
                              wavenumber * wavenumber);
        // Push the MDLeanEvent but correct the weight.
        box->addEvent(MDE(float(it->weight() * correct),
                          float(it->errorSquared() * correct * correct),
                          center));
      } else {
        // Push the MDLeanEvent with the same weight
        box->addEvent(
            MDE(float(it->weight()), float(it->errorSquared()), center));
      }
    }

    // Clear out the EventList to save memory
    if (ClearInputWorkspace)
      el.clear();
  }
  prog->reportIncrement(numEvents, "Adding Events");
}