/** Executes the algorithm * @throw Exception::FileError If the calibration file cannot be opened and read successfully * @throw Exception::InstrumentDefinitionError If unable to obtain the source-sample distance */ void CaltoDspacemap::exec() { MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); const std::string DFileName = getProperty("DspacemapFile"); const std::string calFileName = getProperty("CalibrationFile"); progress(0.0,"Reading calibration file"); IAlgorithm_sptr alg = createSubAlgorithm("LoadCalFile", 0.0, 0.5, true); alg->setProperty("InputWorkspace", inputWS); alg->setPropertyValue("CalFilename", calFileName); alg->setProperty<bool>("MakeGroupingWorkspace", false); alg->setProperty<bool>("MakeOffsetsWorkspace", true); alg->setProperty<bool>("MakeMaskWorkspace", false); alg->setPropertyValue("WorkspaceName", "temp"); alg->executeAsSubAlg(); OffsetsWorkspace_sptr offsetsWS; offsetsWS = alg->getProperty("OutputOffsetsWorkspace"); progress(0.5,"Saving dspacemap file"); alg = createSubAlgorithm("SaveDspacemap", 0.5, 1.0, true); alg->setPropertyValue("DspacemapFile", DFileName); alg->setProperty<int>("PadDetID", getProperty("PadDetID")); alg->setProperty("InputWorkspace", offsetsWS); alg->executeAsSubAlg(); }
/** Load logs from Nexus file. Logs are expected to be in * /raw_data_1/runlog group of the file. Call to this method must be done * within /raw_data_1 group. * @param ws :: The workspace to load the logs to. * @param period :: The period of this workspace */ void LoadISISNexus2::loadLogs(DataObjects::Workspace2D_sptr ws, int period) { IAlgorithm_sptr alg = createSubAlgorithm("LoadNexusLogs", 0.0, 0.5); alg->setPropertyValue("Filename", this->getProperty("Filename")); alg->setProperty<MatrixWorkspace_sptr>("Workspace", ws); try { alg->executeAsSubAlg(); } catch(std::runtime_error&) { g_log.warning() << "Unable to load run logs. There will be no log " << "data associated with this workspace\n"; return; } ws->populateInstrumentParameters(); // If we loaded an icp_event log then create the necessary period logs if( ws->run().hasProperty("icp_event") ) { Kernel::Property *log = ws->run().getProperty("icp_event"); LogParser parser(log); ws->mutableRun().addProperty(parser.createPeriodLog(period)); ws->mutableRun().addProperty(parser.createAllPeriodsLog()); } }
void SphericalAbsorption::exec() { // Retrieve the input workspace m_inputWS = getProperty("InputWorkspace"); // Get the input parameters retrieveBaseProperties(); // Create the output workspace MatrixWorkspace_sptr correctionFactors = WorkspaceFactory::Instance().create(m_inputWS); correctionFactors->isDistribution(true); // The output of this is a distribution correctionFactors->setYUnit(""); // Need to explicitly set YUnit to nothing correctionFactors->setYUnitLabel("Attenuation factor"); double m_sphRadius = getProperty("SphericalSampleRadius"); // in cm IAlgorithm_sptr anvred = createSubAlgorithm("AnvredCorrection"); anvred->setProperty<MatrixWorkspace_sptr>("InputWorkspace", m_inputWS); anvred->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", correctionFactors); anvred->setProperty("PreserveEvents", true); anvred->setProperty("ReturnTransmissionOnly", true); anvred->setProperty("LinearScatteringCoef", m_refAtten); anvred->setProperty("LinearAbsorptionCoef", m_scattering); anvred->setProperty("Radius", m_sphRadius); anvred->executeAsSubAlg(); // Get back the result correctionFactors = anvred->getProperty("OutputWorkspace"); setProperty("OutputWorkspace", correctionFactors); }
void DiffractionEventCalibrateDetectors::movedetector(double x, double y, double z, double rotx, double roty, double rotz, std::string detname, MatrixWorkspace_sptr inputW) { IAlgorithm_sptr alg1 = createSubAlgorithm("MoveInstrumentComponent"); alg1->setProperty<MatrixWorkspace_sptr>("Workspace", inputW); alg1->setPropertyValue("ComponentName", detname); //Move in cm for small shifts alg1->setProperty("X", x*0.01); alg1->setProperty("Y", y*0.01); alg1->setProperty("Z", z*0.01); alg1->setPropertyValue("RelativePosition", "1"); alg1->executeAsSubAlg(); IAlgorithm_sptr algx = createSubAlgorithm("RotateInstrumentComponent"); algx->setProperty<MatrixWorkspace_sptr>("Workspace", inputW); algx->setPropertyValue("ComponentName", detname); algx->setProperty("X", 1.0); algx->setProperty("Y", 0.0); algx->setProperty("Z", 0.0); algx->setProperty("Angle", rotx); algx->setPropertyValue("RelativeRotation", "1"); algx->executeAsSubAlg(); IAlgorithm_sptr algy = createSubAlgorithm("RotateInstrumentComponent"); algy->setProperty<MatrixWorkspace_sptr>("Workspace", inputW); algy->setPropertyValue("ComponentName", detname); algy->setProperty("X", 0.0); algy->setProperty("Y", 1.0); algy->setProperty("Z", 0.0); algy->setProperty("Angle", roty); algy->setPropertyValue("RelativeRotation", "1"); algy->executeAsSubAlg(); IAlgorithm_sptr algz = createSubAlgorithm("RotateInstrumentComponent"); algz->setProperty<MatrixWorkspace_sptr>("Workspace", inputW); algz->setPropertyValue("ComponentName", detname); algz->setProperty("X", 0.0); algz->setProperty("Y", 0.0); algz->setProperty("Z", 1.0); algz->setProperty("Angle", rotz); algz->setPropertyValue("RelativeRotation", "1"); algz->executeAsSubAlg(); }
/** * Run the MoveInstrumentComponent algorithm as a child algorithm * @param comp_name :: The component name * @param zshift :: The shift along the Z-axis * @param start_progress :: The starting percentage for progress reporting * @param end_progress :: The end percentage for progress reporting */ void LoadLOQDistancesFromRaw::performMoveComponent(const std::string & comp_name, double zshift, double start_progress, double end_progress) { IAlgorithm_sptr alg = createSubAlgorithm("MoveInstrumentComponent", start_progress, end_progress); alg->setPropertyValue("Workspace", getPropertyValue("InputWorkspace")); alg->setPropertyValue("ComponentName", comp_name); alg->setProperty("Z", zshift); alg->setPropertyValue("RelativePosition", "1"); alg->executeAsSubAlg(); }
/// Calls CropWorkspace as a sub-algorithm to remove bins from the start or end of a square workspace void RemoveBins::crop(const double& start, const double& end) { IAlgorithm_sptr childAlg = createSubAlgorithm("CropWorkspace"); childAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", boost::const_pointer_cast<MatrixWorkspace>(m_inputWorkspace)); childAlg->setProperty<double>("XMin", start); childAlg->setProperty<double>("XMax", end); childAlg->executeAsSubAlg(); // Only get to here if successful // Assign the result to the output workspace property MatrixWorkspace_sptr outputWS = childAlg->getProperty("OutputWorkspace"); setProperty("OutputWorkspace",outputWS); return; }
void CloneMDWorkspace::doClone(const typename MDEventWorkspace<MDE, nd>::sptr ws) { std::string outWSName = getPropertyValue("OutputWorkspace"); Progress prog(this, 0.0, 10.0, 100); BoxController_sptr bc = ws->getBoxController(); if (!bc) throw std::runtime_error("Error with InputWorkspace: no BoxController!"); if (bc->isFileBacked()) { // Generate a new filename to copy to prog.report("Copying File"); std::string originalFile = bc->getFilename(); std::string outFilename = getPropertyValue("Filename"); if (outFilename.empty()) { // Auto-generated name Poco::Path path = Poco::Path(originalFile).absolute(); std::string newName = path.getBaseName() + "_clone." + path.getExtension(); path.setFileName(newName); outFilename = path.toString(); } // Perform the copying g_log.notice() << "Cloned workspace file being copied to: " << outFilename << std::endl; Poco::File(originalFile).copyTo(outFilename); g_log.information() << "File copied successfully." << std::endl; // Now load it back IAlgorithm_sptr alg = createSubAlgorithm("LoadMD", 0.5, 1.0, false); alg->setPropertyValue("Filename", outFilename); alg->setPropertyValue("FileBackEnd", "1"); alg->setPropertyValue("Memory", "0"); //TODO: How much memory? alg->setPropertyValue("OutputWorkspace", outWSName); alg->executeAsSubAlg(); // Set the output workspace to this IMDEventWorkspace_sptr outWS = alg->getProperty("OutputWorkspace"); this->setProperty("OutputWorkspace", outWS); } else { // Perform the clone in memory. boost::shared_ptr<MDEventWorkspace<MDE,nd> > outWS(new MDEventWorkspace<MDE,nd>(*ws)); this->setProperty("OutputWorkspace", boost::dynamic_pointer_cast<IMDEventWorkspace>(outWS) ); } }
/// Move the detector according to the beam center void EQSANSLoad::moveToBeamCenter() { // Check that we have a beam center defined, otherwise set the // default beam center if (isEmpty(m_center_x) || isEmpty(m_center_y)) { EQSANSInstrument::getDefaultBeamCenter(dataWS, m_center_x, m_center_y); g_log.information() << "No beam finding method: setting to default [" << Poco::NumberFormatter::format(m_center_x, 1) << ", " << Poco::NumberFormatter::format(m_center_y, 1) << "]" << std::endl; return; } // Check that the center of the detector really is at (0,0) int nx_pixels = (int)(dataWS->getInstrument()->getNumberParameter("number-of-x-pixels")[0]); int ny_pixels = (int)(dataWS->getInstrument()->getNumberParameter("number-of-y-pixels")[0]); V3D pixel_first = dataWS->getInstrument()->getDetector(0)->getPos(); int detIDx = EQSANSInstrument::getDetectorFromPixel(nx_pixels-1, 0, dataWS); int detIDy = EQSANSInstrument::getDetectorFromPixel(0, ny_pixels-1, dataWS); V3D pixel_last_x = dataWS->getInstrument()->getDetector(detIDx)->getPos(); V3D pixel_last_y = dataWS->getInstrument()->getDetector(detIDy)->getPos(); double x_offset = (pixel_first.X()+pixel_last_x.X())/2.0; double y_offset = (pixel_first.Y()+pixel_last_y.Y())/2.0; double beam_ctr_x = 0.0; double beam_ctr_y = 0.0; EQSANSInstrument::getCoordinateFromPixel(m_center_x, m_center_y, dataWS, beam_ctr_x, beam_ctr_y); IAlgorithm_sptr mvAlg = createSubAlgorithm("MoveInstrumentComponent", 0.5, 0.50); mvAlg->setProperty<MatrixWorkspace_sptr>("Workspace", dataWS); mvAlg->setProperty("ComponentName", "detector1"); mvAlg->setProperty("X", -x_offset-beam_ctr_x); mvAlg->setProperty("Y", -y_offset-beam_ctr_y); mvAlg->setProperty("RelativePosition", true); mvAlg->executeAsSubAlg(); m_output_message += " Beam center offset: " + Poco::NumberFormatter::format(x_offset) + ", " + Poco::NumberFormatter::format(y_offset) + " m\n"; //m_output_message += " Beam center in real-space: " + Poco::NumberFormatter::format(-x_offset-beam_ctr_x) // + ", " + Poco::NumberFormatter::format(-y_offset-beam_ctr_y) + " m\n"; g_log.information() << "Moving beam center to " << m_center_x << " " << m_center_y << std::endl; dataWS->mutableRun().addProperty("beam_center_x", m_center_x, "pixel", true); dataWS->mutableRun().addProperty("beam_center_y", m_center_y, "pixel", true); m_output_message += " Beam center: " + Poco::NumberFormatter::format(m_center_x, 1) + ", " + Poco::NumberFormatter::format(m_center_y, 1) + "\n"; }
/** Calls CropWorkspace as a sub-algorithm and passes to it the InputWorkspace property * @param specInd :: the index number of the histogram to extract * @param start :: the number of the first bin to include (starts counting bins at 0) * @param end :: the number of the last bin to include (starts counting bins at 0) * @throw out_of_range if start, end or specInd are set outside of the vaild range for the workspace * @throw runtime_error if the algorithm just falls over * @throw invalid_argument if the input workspace does not have common binning */ void GetEi::extractSpec(int64_t specInd, double start, double end) { IAlgorithm_sptr childAlg = createSubAlgorithm("CropWorkspace", 100*m_fracCompl, 100*(m_fracCompl+CROP) ); m_fracCompl += CROP; childAlg->setPropertyValue( "InputWorkspace", getPropertyValue("InputWorkspace") ); childAlg->setProperty( "XMin", start); childAlg->setProperty( "XMax", end); childAlg->setProperty( "StartWorkspaceIndex", specInd); childAlg->setProperty( "EndWorkspaceIndex", specInd); childAlg->executeAsSubAlg(); m_tempWS = childAlg->getProperty("OutputWorkspace"); //DEBUGGING CODE uncomment out the line below if you want to see the TOF window that was analysed //AnalysisDataService::Instance().addOrReplace("croped_dist_del", m_tempWS); progress(m_fracCompl); interruption_point(); }
void EQSANSLoad::exec() { // Read in default TOF cuts m_low_TOF_cut = getProperty("LowTOFCut"); m_high_TOF_cut = getProperty("HighTOFCut"); // Read in default beam center m_center_x = getProperty("BeamCenterX"); m_center_y = getProperty("BeamCenterY"); TableWorkspace_sptr reductionTable = getProperty("ReductionTableWorkspace"); ReductionTableHandler reductionHandler(reductionTable); if (!reductionTable) { const std::string reductionTableName = getPropertyValue("ReductionTableWorkspace"); if (reductionTableName.size()>0) setProperty("ReductionTableWorkspace", reductionHandler.getTable()); } if (reductionHandler.findStringEntry("LoadAlgorithm").size()==0) reductionHandler.addEntry("LoadAlgorithm", toString()); const std::string fileName = getPropertyValue("Filename"); // Output log m_output_message = ""; IAlgorithm_sptr loadAlg = createSubAlgorithm("LoadEventNexus", 0, 0.2); loadAlg->setProperty("Filename", fileName); loadAlg->executeAsSubAlg(); IEventWorkspace_sptr dataWS_tmp = loadAlg->getProperty("OutputWorkspace"); dataWS = boost::dynamic_pointer_cast<MatrixWorkspace>(dataWS_tmp); // Get the sample-detector distance double sdd = 0.0; const double sample_det_dist = getProperty("SampleDetectorDistance"); if (!isEmpty(sample_det_dist)) { sdd = sample_det_dist; } else { Mantid::Kernel::Property* prop = dataWS->run().getProperty("detectorZ"); Mantid::Kernel::TimeSeriesProperty<double>* dp = dynamic_cast<Mantid::Kernel::TimeSeriesProperty<double>* >(prop); sdd = dp->getStatistics().mean; // Modify SDD according to offset if given const double sample_det_offset = getProperty("SampleDetectorDistanceOffset"); if (!isEmpty(sample_det_offset)) { sdd += sample_det_offset; } } dataWS->mutableRun().addProperty("sample_detector_distance", sdd, "mm", true); // Move the detector to its correct position IAlgorithm_sptr mvAlg = createSubAlgorithm("MoveInstrumentComponent", 0.2, 0.4); mvAlg->setProperty<MatrixWorkspace_sptr>("Workspace", dataWS); mvAlg->setProperty("ComponentName", "detector1"); mvAlg->setProperty("Z", sdd/1000.0); mvAlg->setProperty("RelativePosition", false); mvAlg->executeAsSubAlg(); g_log.information() << "Moving detector to " << sdd/1000.0 << std::endl; m_output_message += " Detector position: " + Poco::NumberFormatter::format(sdd/1000.0, 3) + " m\n"; // Get the run number so we can find the proper config file int run_number = 0; std::string config_file = ""; if (dataWS->run().hasProperty("run_number")) { Mantid::Kernel::Property* prop = dataWS->run().getProperty("run_number"); Mantid::Kernel::PropertyWithValue<std::string>* dp = dynamic_cast<Mantid::Kernel::PropertyWithValue<std::string>* >(prop); const std::string run_str = *dp; Poco::NumberParser::tryParse(run_str, run_number); // Find a proper config file config_file = findConfigFile(run_number); } else { g_log.error() << "Could not find run number for workspace " << getPropertyValue("OutputWorkspace") << std::endl; m_output_message += " Could not find run number for data file\n"; } // Process the config file bool use_config = getProperty("UseConfig"); if (use_config && config_file.size()>0) { readConfigFile(config_file); } else if (use_config) { use_config = false; g_log.error() << "Cound not find config file for workspace " << getPropertyValue("OutputWorkspace") << std::endl; m_output_message += " Could not find configuration file for run " + Poco::NumberFormatter::format(run_number) + "\n"; } // If we use the config file, move the moderator position if (use_config) { if (m_moderator_position > -13.0) g_log.error() << "Moderator position seems close to the sample, please check" << std::endl; g_log.information() << "Moving moderator to " << m_moderator_position << std::endl; m_output_message += " Moderator position: " + Poco::NumberFormatter::format(m_moderator_position, 3) + " m\n"; mvAlg = createSubAlgorithm("MoveInstrumentComponent", 0.4, 0.45); mvAlg->setProperty<MatrixWorkspace_sptr>("Workspace", dataWS); mvAlg->setProperty("ComponentName", "moderator"); mvAlg->setProperty("Z", m_moderator_position); mvAlg->setProperty("RelativePosition", false); mvAlg->executeAsSubAlg(); } // Get source aperture radius getSourceSlitSize(); // Move the beam center to its proper position moveToBeamCenter(); // Modify TOF bool correct_for_flight_path = getProperty("CorrectForFlightPath"); m_output_message += " Flight path correction "; if (!correct_for_flight_path) m_output_message += "NOT "; m_output_message += "applied\n"; DataObjects::EventWorkspace_sptr dataWS_evt = boost::dynamic_pointer_cast<EventWorkspace>(dataWS_tmp); IAlgorithm_sptr tofAlg = createSubAlgorithm("EQSANSTofStructure", 0.5, 0.7); tofAlg->setProperty<EventWorkspace_sptr>("InputWorkspace", dataWS_evt); tofAlg->setProperty("LowTOFCut", m_low_TOF_cut); tofAlg->setProperty("HighTOFCut", m_high_TOF_cut); tofAlg->setProperty("FlightPathCorrection", correct_for_flight_path); tofAlg->executeAsSubAlg(); const double wl_min = tofAlg->getProperty("WavelengthMin"); const double wl_max = tofAlg->getProperty("WavelengthMax"); const bool frame_skipping = tofAlg->getProperty("FrameSkipping"); dataWS->mutableRun().addProperty("wavelength_min", wl_min, "Angstrom", true); dataWS->mutableRun().addProperty("wavelength_max", wl_max, "Angstrom", true); dataWS->mutableRun().addProperty("is_frame_skipping", int(frame_skipping), true); double wl_combined_max = wl_max; m_output_message += " Wavelength range: " + Poco::NumberFormatter::format(wl_min, 1) + " - " + Poco::NumberFormatter::format(wl_max, 1); if (frame_skipping) { const double wl_min2 = tofAlg->getProperty("WavelengthMinFrame2"); const double wl_max2 = tofAlg->getProperty("WavelengthMaxFrame2"); wl_combined_max = wl_max2; dataWS->mutableRun().addProperty("wavelength_min_frame2", wl_min2, "Angstrom", true); dataWS->mutableRun().addProperty("wavelength_max_frame2", wl_max2, "Angstrom", true); m_output_message += " and " + Poco::NumberFormatter::format(wl_min2, 1) + " - " + Poco::NumberFormatter::format(wl_max2, 1) + " Angstrom\n"; } else m_output_message += " Angstrom\n"; // Convert to wavelength const double ssd = fabs(dataWS->getInstrument()->getSource()->getPos().Z())*1000.0; const double conversion_factor = 3.9560346 / (sdd+ssd); m_output_message += " TOF to wavelength conversion factor: " + Poco::NumberFormatter::format(conversion_factor) + "\n"; IAlgorithm_sptr scAlg = createSubAlgorithm("ScaleX", 0.7, 0.71); scAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS); scAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS); scAlg->setProperty("Factor", conversion_factor); scAlg->executeAsSubAlg(); dataWS->getAxis(0)->setUnit("Wavelength"); // Rebin so all the wavelength bins are aligned const bool preserveEvents = getProperty("PreserveEvents"); std::string params = Poco::NumberFormatter::format(wl_min, 2) + ",0.1," + Poco::NumberFormatter::format(wl_combined_max, 2); IAlgorithm_sptr rebinAlg = createSubAlgorithm("Rebin", 0.71, 0.72); rebinAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS); if (preserveEvents) rebinAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS); rebinAlg->setPropertyValue("Params", params); rebinAlg->setProperty("PreserveEvents", preserveEvents); rebinAlg->executeAsSubAlg(); if (!preserveEvents) dataWS = rebinAlg->getProperty("OutputWorkspace"); dataWS->mutableRun().addProperty("event_ws", getPropertyValue("OutputWorkspace"), true); setProperty<MatrixWorkspace_sptr>("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(dataWS)); setPropertyValue("OutputMessage", m_output_message); }
/** Executes the algorithm * * @throw runtime_error Thrown if algorithm cannot execute */ void DiffractionEventCalibrateDetectors::exec() { // Try to retrieve optional properties const int maxIterations = getProperty("MaxIterations"); const double peakOpt = getProperty("LocationOfPeakToOptimize"); // Get the input workspace EventWorkspace_const_sptr inputW = getProperty("InputWorkspace"); // retrieve the properties const std::string rb_params=getProperty("Params"); //Get some stuff from the input workspace Instrument_const_sptr inst = inputW->getInstrument(); //Build a list of Rectangular Detectors std::vector<boost::shared_ptr<RectangularDetector> > detList; // --------- Loading only one bank ---------------------------------- std::string onebank = getProperty("BankName"); bool doOneBank = (onebank != ""); for (int i=0; i < inst->nelements(); i++) { boost::shared_ptr<RectangularDetector> det; boost::shared_ptr<ICompAssembly> assem; boost::shared_ptr<ICompAssembly> assem2; det = boost::dynamic_pointer_cast<RectangularDetector>( (*inst)[i] ); if (det) { if (det->getName().compare(onebank) == 0) detList.push_back(det); if (!doOneBank) detList.push_back(det); } else { //Also, look in the first sub-level for RectangularDetectors (e.g. PG3). // We are not doing a full recursive search since that will be very long for lots of pixels. assem = boost::dynamic_pointer_cast<ICompAssembly>( (*inst)[i] ); if (assem) { for (int j=0; j < assem->nelements(); j++) { det = boost::dynamic_pointer_cast<RectangularDetector>( (*assem)[j] ); if (det) { if (det->getName().compare(onebank) == 0) detList.push_back(det); if (!doOneBank) detList.push_back(det); } else { //Also, look in the second sub-level for RectangularDetectors (e.g. PG3). // We are not doing a full recursive search since that will be very long for lots of pixels. assem2 = boost::dynamic_pointer_cast<ICompAssembly>( (*assem)[j] ); if (assem2) { for (int k=0; k < assem2->nelements(); k++) { det = boost::dynamic_pointer_cast<RectangularDetector>( (*assem2)[k] ); if (det) { if (det->getName().compare(onebank) == 0) detList.push_back(det); if (!doOneBank) detList.push_back(det); } } } } } } } } // set-up minimizer std::string inname = getProperty("InputWorkspace"); std::string outname = inname+"2"; //getProperty("OutputWorkspace"); IAlgorithm_sptr algS = createSubAlgorithm("SortEvents"); algS->setPropertyValue("InputWorkspace",inname); algS->setPropertyValue("SortBy", "X Value"); algS->executeAsSubAlg(); inputW=algS->getProperty("InputWorkspace"); //Write DetCal File double baseX,baseY,baseZ,upX,upY,upZ; std::string filename=getProperty("DetCalFilename"); std::fstream outfile; outfile.open(filename.c_str(), std::ios::out); if(detList.size() > 1) { outfile << "#\n"; outfile << "# Mantid Optimized .DetCal file for SNAP with TWO detector panels\n"; outfile << "# Old Panel, nominal size and distance at -90 degrees.\n"; outfile << "# New Panel, nominal size and distance at +90 degrees.\n"; outfile << "#\n"; outfile << "# Lengths are in centimeters.\n"; outfile << "# Base and up give directions of unit vectors for a local\n"; outfile << "# x,y coordinate system on the face of the detector.\n"; outfile << "#\n"; std::time_t current_t = DateAndTime::get_current_time().to_time_t() ; std::tm * current = gmtime( ¤t_t ); outfile << "# "<<asctime (current) <<"\n"; outfile << "#\n"; outfile << "6 L1 T0_SHIFT\n"; IObjComponent_const_sptr source = inst->getSource(); IObjComponent_const_sptr sample = inst->getSample(); outfile << "7 "<<source->getDistance(*sample)*100<<" 0\n"; outfile << "4 DETNUM NROWS NCOLS WIDTH HEIGHT DEPTH DETD CenterX CenterY CenterZ BaseX BaseY BaseZ UpX UpY UpZ\n"; } Progress prog(this,0.0,1.0,detList.size()); for (int det=0; det < static_cast<int>(detList.size()); det++) { std::string par[6]; par[0]=detList[det]->getName(); par[1]=inname; par[2]=outname; std::ostringstream strpeakOpt; strpeakOpt<<peakOpt; par[3]=strpeakOpt.str(); par[4]=rb_params; // --- Create a GroupingWorkspace for this detector name ------ CPUTimer tim; IAlgorithm_sptr alg2 = AlgorithmFactory::Instance().create("CreateGroupingWorkspace", 1); alg2->initialize(); alg2->setPropertyValue("InputWorkspace", getPropertyValue("InputWorkspace")); alg2->setPropertyValue("GroupNames", detList[det]->getName()); std::string groupWSName = "group_" + detList[det]->getName(); alg2->setPropertyValue("OutputWorkspace", groupWSName); alg2->executeAsSubAlg(); par[5] = groupWSName; std::cout << tim << " to CreateGroupingWorkspace" << std::endl; const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex; gsl_multimin_fminimizer *s = NULL; gsl_vector *ss, *x; gsl_multimin_function minex_func; // finally do the fitting int nopt = 6; int iter = 0; int status = 0; double size; /* Starting point */ x = gsl_vector_alloc (nopt); gsl_vector_set (x, 0, 0.0); gsl_vector_set (x, 1, 0.0); gsl_vector_set (x, 2, 0.0); gsl_vector_set (x, 3, 0.0); gsl_vector_set (x, 4, 0.0); gsl_vector_set (x, 5, 0.0); /* Set initial step sizes to 0.1 */ ss = gsl_vector_alloc (nopt); gsl_vector_set_all (ss, 0.1); /* Initialize method and iterate */ minex_func.n = nopt; minex_func.f = &Mantid::Algorithms::gsl_costFunction; minex_func.params = ∥ s = gsl_multimin_fminimizer_alloc (T, nopt); gsl_multimin_fminimizer_set (s, &minex_func, x, ss); do { iter++; status = gsl_multimin_fminimizer_iterate(s); if (status) break; size = gsl_multimin_fminimizer_size (s); status = gsl_multimin_test_size (size, 1e-2); } while (status == GSL_CONTINUE && iter < maxIterations && s->fval != -0.000 ); // Output summary to log file if (s->fval != -0.000) movedetector(gsl_vector_get (s->x, 0), gsl_vector_get (s->x, 1), gsl_vector_get (s->x, 2), gsl_vector_get (s->x, 3), gsl_vector_get (s->x, 4), gsl_vector_get (s->x, 5), par[0], getProperty("InputWorkspace")); else { gsl_vector_set (s->x, 0, 0.0); gsl_vector_set (s->x, 1, 0.0); gsl_vector_set (s->x, 2, 0.0); gsl_vector_set (s->x, 3, 0.0); gsl_vector_set (s->x, 4, 0.0); gsl_vector_set (s->x, 5, 0.0); } std::string reportOfDiffractionEventCalibrateDetectors = gsl_strerror(status); if (s->fval == -0.000) reportOfDiffractionEventCalibrateDetectors = "No events"; g_log.information() << "Detector = " << det << "\n" << "Method used = " << "Simplex" << "\n" << "Iteration = " << iter << "\n" << "Status = " << reportOfDiffractionEventCalibrateDetectors << "\n" << "Minimize PeakLoc-" << peakOpt << " = " << s->fval << "\n"; //Move in cm for small shifts g_log.information() << "Move (X) = " << gsl_vector_get (s->x, 0)*0.01 << " \n"; g_log.information() << "Move (Y) = " << gsl_vector_get (s->x, 1)*0.01 << " \n"; g_log.information() << "Move (Z) = " << gsl_vector_get (s->x, 2)*0.01 << " \n"; g_log.information() << "Rotate (X) = " << gsl_vector_get (s->x, 3) << " \n"; g_log.information() << "Rotate (Y) = " << gsl_vector_get (s->x, 4) << " \n"; g_log.information() << "Rotate (Z) = " << gsl_vector_get (s->x, 5) << " \n"; Kernel::V3D CalCenter=V3D(gsl_vector_get (s->x, 0)*0.01, gsl_vector_get (s->x, 1)*0.01, gsl_vector_get (s->x, 2)*0.01); Kernel::V3D Center=detList[det]->getPos()+CalCenter; int pixmax = detList[det]->xpixels()-1; int pixmid = (detList[det]->ypixels()-1)/2; BoundingBox box; detList[det]->getAtXY(pixmax, pixmid)->getBoundingBox(box); baseX = box.xMax(); baseY = box.yMax(); baseZ = box.zMax(); Kernel::V3D Base=V3D(baseX,baseY,baseZ)+CalCenter; pixmid = (detList[det]->xpixels()-1)/2; pixmax = detList[det]->ypixels()-1; detList[det]->getAtXY(pixmid, pixmax)->getBoundingBox(box); upX = box.xMax(); upY = box.yMax(); upZ = box.zMax(); Kernel::V3D Up=V3D(upX,upY,upZ)+CalCenter; Base-=Center; Up-=Center; //Rotate around x baseX = Base[0]; baseY = Base[1]; baseZ = Base[2]; double deg2rad=M_PI/180.0; double angle = gsl_vector_get (s->x, 3)*deg2rad; Base=V3D(baseX,baseY*cos(angle)-baseZ*sin(angle), baseY*sin(angle)+baseZ*cos(angle)); upX = Up[0]; upY = Up[1]; upZ = Up[2]; Up=V3D(upX,upY*cos(angle)-upZ*sin(angle), upY*sin(angle)+upZ*cos(angle)); //Rotate around y baseX = Base[0]; baseY = Base[1]; baseZ = Base[2]; angle = gsl_vector_get (s->x, 4)*deg2rad; Base=V3D(baseZ*sin(angle)+baseX*cos(angle), baseY,baseZ*cos(angle)-baseX*sin(angle)); upX = Up[0]; upY = Up[1]; upZ = Up[2]; Up=V3D(upZ*cos(angle)-upX*sin(angle),upY, upZ*sin(angle)+upX*cos(angle)); //Rotate around z baseX = Base[0]; baseY = Base[1]; baseZ = Base[2]; angle = gsl_vector_get (s->x, 5)*deg2rad; Base=V3D(baseX*cos(angle)-baseY*sin(angle), baseX*sin(angle)+baseY*cos(angle),baseZ); upX = Up[0]; upY = Up[1]; upZ = Up[2]; Up=V3D(upX*cos(angle)-upY*sin(angle), upX*sin(angle)+upY*cos(angle),upZ); Base.normalize(); Up.normalize(); Center*=100.0; // << det+1 << " " outfile << "5 " << detList[det]->getName().substr(4) << " " << detList[det]->xpixels() << " " << detList[det]->ypixels() << " " << 100.0*detList[det]->xsize() << " " << 100.0*detList[det]->ysize() << " " << "0.2000" << " " << Center.norm() << " " ; Center.write(outfile); outfile << " "; Base.write(outfile); outfile << " "; Up.write(outfile); outfile << "\n"; // clean up dynamically allocated gsl stuff gsl_vector_free(x); gsl_vector_free(ss); gsl_multimin_fminimizer_free (s); // Remove the now-unneeded grouping workspace AnalysisDataService::Instance().remove(groupWSName); prog.report(detList[det]->getName()); } // Closing outfile.close(); return; }