void CorrectKiKf::correctKiKfEventHelper(std::vector<T>& wevector, double efixed,const std::string emodeStr) { double Ei,Ef; float kioverkf; typename std::vector<T>::iterator it; for (it=wevector.begin(); it<wevector.end();) { if (emodeStr == "Direct") //Ei=Efixed { Ei = efixed; Ef = Ei - it->tof(); } else //Ef=Efixed { Ef = efixed; Ei = Ef + it->tof(); } // if Ei or Ef is negative, delete the event if ((Ei <= 0)||(Ef <= 0)) { it=wevector.erase(it); } else { kioverkf = static_cast<float>(std::sqrt( Ei / Ef )); it->m_weight*=kioverkf; it->m_errorSquared*=kioverkf*kioverkf; ++it; } } }
void SaveNexusProcessed::appendEventListData(std::vector<T> events, size_t offset, double *tofs, float *weights, float *errorSquareds, int64_t *pulsetimes) { // Do nothing if there are no events. if (events.empty()) return; typename std::vector<T>::const_iterator it; typename std::vector<T>::const_iterator it_end = events.end(); size_t i = offset; // Fill the C-arrays with the fields from all the events, as requested. for (it = events.begin(); it != it_end; it++) { if (tofs) tofs[i] = it->tof(); if (weights) weights[i] = static_cast<float>(it->weight()); if (errorSquareds) errorSquareds[i] = static_cast<float>(it->errorSquared()); if (pulsetimes) pulsetimes[i] = it->pulseTime().totalNanoseconds(); i++; } }
void UnaryOperation::unaryOperationEventHelper(std::vector<T> &wevector) { typename std::vector<T>::iterator it; for (it = wevector.begin(); it < wevector.end(); ++it) { double yout, eout; // Call the abstract function, passing in the current values performUnaryOperation(it->tof(), it->weight(), std::sqrt(it->errorSquared()), yout, eout); it->m_weight = static_cast<float>(yout); it->m_errorSquared = static_cast<float>(eout * eout); } }
void NexusFileIO::writeEventListData( std::vector<T> events, bool writeTOF, bool writePulsetime, bool writeWeight, bool writeError) const { // Do nothing if there are no events. if (events.empty()) return; size_t num = events.size(); double * tofs = new double[num]; double * weights = new double[num]; double * errorSquareds = new double[num]; int64_t * pulsetimes = new int64_t[num]; typename std::vector<T>::const_iterator it; typename std::vector<T>::const_iterator it_end = events.end(); size_t i = 0; // Fill the C-arrays with the fields from all the events, as requested. for (it = events.begin(); it != it_end; it++) { if (writeTOF) tofs[i] = it->tof(); if (writePulsetime) pulsetimes[i] = it->pulseTime().totalNanoseconds(); if (writeWeight) weights[i] = it->weight(); if (writeError) errorSquareds[i] = it->errorSquared(); i++; } // Write out all the required arrays. int dims_array[1] = { static_cast<int>(num) }; // In this mode, compressing makes things extremely slow! Not to be used for managed event workspaces. bool compress = true; //(num > 100); if (writeTOF) NXwritedata("tof", NX_FLOAT64, 1, dims_array, (void *)(tofs), compress); if (writePulsetime) NXwritedata("pulsetime", NX_INT64, 1, dims_array, (void *)(pulsetimes), compress); if (writeWeight) NXwritedata("weight", NX_FLOAT32, 1, dims_array, (void *)(weights), compress); if (writeError) NXwritedata("error_squared", NX_FLOAT32, 1, dims_array, (void *)(errorSquareds), compress); // Free mem. delete [] tofs; delete [] weights; delete [] errorSquareds; delete [] pulsetimes; }
size_t ConvToMDEventsWS::convertEventList(size_t workspaceIndex) { const Mantid::DataObjects::EventList &el = m_EventWS->getEventList(workspaceIndex); size_t numEvents = el.getNumberEvents(); if (numEvents == 0) return 0; // create local unit conversion class UnitsConversionHelper localUnitConv(m_UnitConversion); uint32_t detID = m_detID[workspaceIndex]; uint16_t runIndexLoc = m_RunIndex; std::vector<coord_t> locCoord(m_Coord); // set up unit conversion and calculate up all coordinates, which depend on // spectra index only if (!m_QConverter->calcYDepCoordinates(locCoord, workspaceIndex)) return 0; // skip if any y outsize of the range of interest; localUnitConv.updateConversion(workspaceIndex); // // allocate temporary buffers for MD Events data // MD events coordinates buffer std::vector<coord_t> allCoord; std::vector<float> sig_err; // array for signal and error. std::vector<uint16_t> run_index; // Buffer for run index for each event std::vector<uint32_t> det_ids; // Buffer of det Id-s for each event allCoord.reserve(this->m_NDims * numEvents); sig_err.reserve(2 * numEvents); run_index.reserve(numEvents); det_ids.reserve(numEvents); // This little dance makes the getting vector of events more general (since // you can't overload by return type). typename std::vector<T> const *events_ptr; getEventsFrom(el, events_ptr); const typename std::vector<T> &events = *events_ptr; // Iterators to start/end typename std::vector<T>::const_iterator it = events.begin(); typename std::vector<T>::const_iterator it_end = events.end(); it = events.begin(); for (; it != it_end; it++) { double val = localUnitConv.convertUnits(it->tof()); double signal = it->weight(); double errorSq = it->errorSquared(); if (!m_QConverter->calcMatrixCoord(val, locCoord, signal, errorSq)) continue; // skip ND outside the range sig_err.push_back(float(signal)); sig_err.push_back(float(errorSq)); run_index.push_back(runIndexLoc); det_ids.push_back(detID); allCoord.insert(allCoord.end(), locCoord.begin(), locCoord.end()); } // Add them to the MDEW size_t n_added_events = run_index.size(); m_OutWSWrapper->addMDData(sig_err, run_index, det_ids, allCoord, n_added_events); return n_added_events; }
void ConvertToDiffractionMDWorkspace::convertEventList(int workspaceIndex, EventList & el) { size_t numEvents = el.getNumberEvents(); MDEvents::MDBoxBase<MDEvents::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; // 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 typename std::vector<T>::iterator it = events.begin(); typename std::vector<T>::iterator 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, (size_t)2e8); } } prog->reportIncrement(numEvents, "Adding Events"); }