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"); }
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"); }