void ModeratorTzero::exec() { m_tolTOF = getProperty("tolTOF"); //Tolerance in the calculation of the emission time, in microseconds m_niter=getProperty("Niter"); // number of iterations const MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); m_instrument = inputWS->getInstrument(); // pointer to the instrument //deltaE-mode (should be "indirect") std::vector<std::string> Emode=m_instrument->getStringParameter("deltaE-mode"); if(Emode.empty()) throw Exception::InstrumentDefinitionError("Unable to retrieve instrument geometry (direct or indirect) parameter", inputWS->getTitle()); if(Emode[0]!= "indirect") throw Exception::InstrumentDefinitionError("Instrument geometry must be of type indirect."); // extract formula from instrument parameters std::vector<std::string> t0_formula=m_instrument->getStringParameter("t0_formula"); if(t0_formula.empty()) throw Exception::InstrumentDefinitionError("Unable to retrieve t0_formula among instrument parameters"); m_formula=t0_formula[0]; //Run execEvent if eventWorkSpace EventWorkspace_const_sptr eventWS = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS); if (eventWS != NULL) { execEvent(); return; } MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace"); //Check whether input == output to see whether a new workspace is required. if ( outputWS != inputWS ) { //Create new workspace for output from old outputWS = WorkspaceFactory::Instance().create(inputWS); } const size_t numHists = static_cast<size_t>(inputWS->getNumberHistograms()); Progress prog(this,0.0,1.0,numHists); //report progress of algorithm PARALLEL_FOR2(inputWS, outputWS) // iterate over the spectra for (int i=0; i < static_cast<int>(numHists); ++i) { PARALLEL_START_INTERUPT_REGION size_t wsIndex = static_cast<size_t>(i); double L1=CalculateL1(inputWS, wsIndex); // distance from source to sample or monitor double t2=CalculateT2(inputWS, wsIndex); // time from sample to detector // shift the time of flights by the emission time from the moderator if(t2 >= 0) //t2 < 0 when no detector info is available { double E1; mu::Parser parser; parser.DefineVar("incidentEnergy", &E1); // associate E1 to this parser parser.SetExpr(m_formula); E1=m_convfactor*(L1/m_t1min)*(L1/m_t1min); double min_t0_next=parser.Eval(); // fast neutrons are shifted by min_t0_next, irrespective of tof MantidVec &inbins = inputWS->dataX(i); MantidVec &outbins = outputWS->dataX(i); // iterate over the time-of-flight values for(unsigned int ibin=0; ibin < inbins.size(); ibin++) { double tof=inbins[ibin]; // current time-of-flight if(tof<m_t1min+t2) tof-=min_t0_next; else tof-=CalculateT0(tof, L1, t2, E1, parser); outbins[ibin] = tof; } } else { outputWS->dataX(i) = inputWS->dataX(i); } //Copy y and e data outputWS->dataY(i) = inputWS->dataY(i); outputWS->dataE(i) = inputWS->dataE(i); prog.report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // Copy units if (inputWS->getAxis(0)->unit().get()) { outputWS->getAxis(0)->unit() = inputWS->getAxis(0)->unit(); } try { if(inputWS->getAxis(1)->unit().get()) { outputWS->getAxis(1)->unit() = inputWS->getAxis(1)->unit(); } } catch(Exception::IndexError &) { // OK, so this isn't a Workspace2D } // Assign it to the output workspace property setProperty("OutputWorkspace",outputWS); }
/** Checks input properties and compares them to previous values * @param is :: [output] Number of the first run * @param ie :: [output] Number of the last run */ void PlotAsymmetryByLogValue::checkProperties(size_t &is, size_t &ie) { // Log Value m_logName = getPropertyValue("LogValue"); // Get function to apply to logValue m_logFunc = getPropertyValue("Function"); // Get type of computation m_int = (getPropertyValue("Type") == "Integral"); // Get grouping properties m_forward_list = getProperty("ForwardSpectra"); m_backward_list = getProperty("BackwardSpectra"); // Get green and red periods m_red = getProperty("Red"); m_green = getProperty("Green"); // Get time min and time max m_minTime = getProperty("TimeMin"); m_maxTime = getProperty("TimeMax"); // Get type of dead-time corrections m_dtcType = getPropertyValue("DeadTimeCorrType"); m_dtcFile = getPropertyValue("DeadTimeCorrFile"); // Get runs std::string firstFN = getProperty("FirstRun"); std::string lastFN = getProperty("LastRun"); // Parse run names and get the number of runs parseRunNames(firstFN, lastFN, m_filenameBase, m_filenameExt, m_filenameZeros); is = atoi(firstFN.c_str()); // starting run number ie = atoi(lastFN.c_str()); // last run number if (ie < is) { throw std::runtime_error( "First run number is greater than last run number"); } // Create a string holding all the properties std::ostringstream ss; ss << m_filenameBase << "," << m_filenameExt << "," << m_filenameZeros << ","; ss << m_dtcType << "," << m_dtcFile << ","; ss << getPropertyValue("ForwardSpectra") << "," << getPropertyValue("BackwardSpectra") << ","; ss << m_int << "," << m_minTime << "," << m_maxTime << ","; ss << m_red << "," << m_green << ","; ss << m_logName << ", " << m_logFunc; m_allProperties = ss.str(); // Check if we can re-use results from previous run // We can reuse results if: // 1. There is a ws in the ADS with name m_currResName // 2. It is a MatrixWorkspace // 3. It has a title equatl to m_allProperties // This ws stores previous results as described below if (AnalysisDataService::Instance().doesExist(m_currResName)) { MatrixWorkspace_sptr prevResults = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( m_currResName); if (prevResults) { if (m_allProperties == prevResults->getTitle()) { // We can re-use results size_t nPoints = prevResults->blocksize(); size_t nHisto = prevResults->getNumberHistograms(); if (nHisto == 2) { // Only 'red' data for (size_t i = 0; i < nPoints; i++) { // The first spectrum contains: X -> run number, Y -> log value // The second spectrum contains: Y -> redY, E -> redE size_t run = static_cast<size_t>(prevResults->readX(0)[i]); if ((run >= is) && (run <= ie)) { m_logValue[run] = prevResults->readY(0)[i]; m_redY[run] = prevResults->readY(1)[i]; m_redE[run] = prevResults->readE(1)[i]; } } } else { // 'Red' and 'Green' data for (size_t i = 0; i < nPoints; i++) { // The first spectrum contains: X -> run number, Y -> log value // The second spectrum contains: Y -> diffY, E -> diffE // The third spectrum contains: Y -> redY, E -> redE // The fourth spectrum contains: Y -> greenY, E -> greeE // The fifth spectrum contains: Y -> sumY, E -> sumE size_t run = static_cast<size_t>(prevResults->readX(0)[i]); if ((run >= is) && (run <= ie)) { m_logValue[run] = prevResults->readY(0)[i]; m_diffY[run] = prevResults->readY(1)[i]; m_diffE[run] = prevResults->readE(1)[i]; m_redY[run] = prevResults->readY(2)[i]; m_redE[run] = prevResults->readE(2)[i]; m_greenY[run] = prevResults->readY(3)[i]; m_greenE[run] = prevResults->readE(3)[i]; m_sumY[run] = prevResults->readY(4)[i]; m_sumE[run] = prevResults->readE(4)[i]; } } } } } } }
//calculate time from sample to detector double ModeratorTzero::CalculateT2(MatrixWorkspace_sptr inputWS, size_t i) { static const double convFact = 1.0e-6*sqrt(2*PhysicalConstants::meV/PhysicalConstants::NeutronMass); double t2(-1.0); // negative initialization signals error // Get detector position IDetector_const_sptr det; try { det = inputWS->getDetector(i); } catch (Exception::NotFoundError&) { return t2; } if( det->isMonitor() ) { t2 = 0.0; //t2=0.0 since there is no sample to detector path } else { IComponent_const_sptr sample = m_instrument->getSample(); // Get final energy E_f, final velocity v_f std::vector< double > wsProp=det->getNumberParameter("Efixed"); if ( !wsProp.empty() ) { double E2 = wsProp.at(0); //[E2]=meV double v2 = convFact * sqrt(E2); //[v2]=meter/microsec try { double L2 = det->getDistance(*sample); t2 = L2 / v2; } catch (Exception::NotFoundError &) { g_log.error("Unable to calculate detector-sample distance"); throw Exception::InstrumentDefinitionError("Unable to calculate detector-sample distance", inputWS->getTitle()); } } else { g_log.debug() <<"Efixed not found for detector "<< i << std::endl; } } return t2; } // end of CalculateT2(const MatrixWorkspace_sptr inputWS, size_t i)