144 double rotz,
const std::string &detname,
const std::string &inname,
145 const std::string &outname,
const std::string &peakOpt,
146 const std::string &rb_param,
const std::string &groupWSName) {
149 std::dynamic_pointer_cast<EventWorkspace>(AnalysisDataService::Instance().retrieve(inname));
154 g_log.
debug() << tim <<
" to movedetector()\n";
158 alg3->setPropertyValue(
"OutputWorkspace", outname);
159 alg3->setPropertyValue(
"Target",
"dSpacing");
160 alg3->executeAsChildAlg();
168 alg4->setPropertyValue(
"GroupingFileName",
"");
169 alg4->setPropertyValue(
"GroupingWorkspace", groupWSName);
170 alg4->executeAsChildAlg();
171 outputW = alg4->getProperty(
"OutputWorkspace");
174 g_log.
debug() << tim <<
" to DiffractionFocussing\n";
179 alg5->setPropertyValue(
"Params", rb_param);
180 alg5->executeAsChildAlg();
181 outputW = alg5->getProperty(
"OutputWorkspace");
186 Mantid::HistogramData::HistogramY
const &yValues = outputW->y(0);
187 auto it = std::max_element(yValues.begin(), yValues.end());
188 double peakHeight = *it;
191 double peakLoc = outputW->x(0)[it - yValues.begin()];
201 std::ostringstream fun_str;
202 fun_str <<
"name=Gaussian,Height=" << peakHeight <<
",Sigma=0.01,PeakCentre=" << peakLoc;
203 fit_alg->setProperty(
"Function", fun_str.str());
204 fit_alg->setProperty(
"InputWorkspace", outputW);
205 fit_alg->setProperty(
"WorkspaceIndex", 0);
206 fit_alg->setProperty(
"StartX", outputW->x(0)[0]);
207 fit_alg->setProperty(
"EndX", outputW->x(0)[outputW->blocksize()]);
208 fit_alg->setProperty(
"MaxIterations", 200);
209 fit_alg->setProperty(
"Output",
"fit");
210 fit_alg->executeAsChildAlg();
214 std::vector<double> params;
216 for (
size_t i = 0; i < fun_res->nParams(); ++i) {
217 params.emplace_back(fun_res->getParameter(i));
219 peakHeight = params[0];
224 g_log.
debug() << tim <<
" to movedetector()\n";
229 return (
static_cast<int>(inputE->getNumberEvents()) / 1.e6) / peakHeight +
230 std::fabs(peakLoc - boost::lexical_cast<double>(peakOpt));
273 const int maxIterations =
getProperty(
"MaxIterations");
274 const double peakOpt =
getProperty(
"LocationOfPeakToOptimize");
280 const std::string rb_params =
getProperty(
"Params");
285 const auto &dummyW = create<EventWorkspace>(*inputW, 1, inputW->binEdges(0));
287 const auto &componentInfo = dummyW->componentInfo();
290 std::vector<size_t> detList;
293 bool doOneBank = (!onebank.empty());
294 for (
size_t i = 0; i < componentInfo.size(); ++i) {
295 if (componentInfo.isGridDetector(i) && (!doOneBank || componentInfo.name(i) == onebank)) {
296 detList.emplace_back(i);
302 std::string inname =
getProperty(
"InputWorkspace");
303 std::string outname = inname +
"2";
306 algS->setProperty(
"InputWorkspace", inputW);
307 algS->setPropertyValue(
"SortBy",
"X Value");
308 algS->executeAsChildAlg();
311 std::string filename =
getProperty(
"DetCalFilename");
312 std::fstream outfile;
313 outfile.open(filename.c_str(), std::ios::out);
315 if (detList.size() > 1) {
317 outfile <<
"# Mantid Optimized .DetCal file for SNAP with TWO detector "
319 outfile <<
"# Old Panel, nominal size and distance at -90 degrees.\n";
320 outfile <<
"# New Panel, nominal size and distance at +90 degrees.\n";
322 outfile <<
"# Lengths are in centimeters.\n";
323 outfile <<
"# Base and up give directions of unit vectors for a local\n";
324 outfile <<
"# x,y coordinate system on the face of the detector.\n";
326 outfile <<
"# " << DateAndTime::getCurrentTime().toFormattedString(
"%c") <<
"\n";
328 outfile <<
"6 L1 T0_SHIFT\n";
331 outfile <<
"7 " << source->getDistance(*sample) * 100 <<
" 0\n";
332 outfile <<
"4 DETNUM NROWS NCOLS WIDTH HEIGHT DEPTH DETD "
333 "CenterX CenterY CenterZ BaseX BaseY BaseZ "
337 Progress prog(
this, 0.0, 1.0, detList.size());
338 for (
int det = 0; det < static_cast<int>(detList.size()); det++) {
339 const size_t bankIndex = detList[det];
340 const std::string bankName = componentInfo.name(bankIndex);
345 std::ostringstream strpeakOpt;
346 strpeakOpt << peakOpt;
347 par[3] = strpeakOpt.str();
352 auto alg2 = AlgorithmFactory::Instance().create(
"CreateGroupingWorkspace", 1);
354 alg2->setProperty(
"InputWorkspace", inputW);
355 alg2->setPropertyValue(
"GroupNames", bankName);
356 std::string groupWSName =
"group_" + bankName;
357 alg2->setPropertyValue(
"OutputWorkspace", groupWSName);
358 alg2->executeAsChildAlg();
359 par[5] = groupWSName;
360 std::cout << tim <<
" to CreateGroupingWorkspace\n";
362 const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
364 gsl_multimin_function minex_func;
373 x = gsl_vector_alloc(nopt);
374 gsl_vector_set(
x, 0, 0.0);
375 gsl_vector_set(
x, 1, 0.0);
376 gsl_vector_set(
x, 2, 0.0);
377 gsl_vector_set(
x, 3, 0.0);
378 gsl_vector_set(
x, 4, 0.0);
379 gsl_vector_set(
x, 5, 0.0);
382 ss = gsl_vector_alloc(nopt);
383 gsl_vector_set_all(ss, 0.1);
388 minex_func.params = ∥
390 gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc(T, nopt);
391 gsl_multimin_fminimizer_set(s, &minex_func,
x, ss);
395 status = gsl_multimin_fminimizer_iterate(s);
400 double size = gsl_multimin_fminimizer_size(s);
401 status = gsl_multimin_test_size(size, 1e-2);
403 }
while (status == GSL_CONTINUE && iter < maxIterations && s->fval != -0.000);
406 if (s->fval != -0.000)
407 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),
408 gsl_vector_get(s->x, 4), gsl_vector_get(s->x, 5), par[0],
getProperty(
"InputWorkspace"));
410 gsl_vector_set(s->x, 0, 0.0);
411 gsl_vector_set(s->x, 1, 0.0);
412 gsl_vector_set(s->x, 2, 0.0);
413 gsl_vector_set(s->x, 3, 0.0);
414 gsl_vector_set(s->x, 4, 0.0);
415 gsl_vector_set(s->x, 5, 0.0);
418 std::string reportOfDiffractionEventCalibrateDetectors = gsl_strerror(status);
419 if (s->fval == -0.000)
420 reportOfDiffractionEventCalibrateDetectors =
"No events";
426 <<
"Iteration = " << iter <<
"\n"
427 <<
"Status = " << reportOfDiffractionEventCalibrateDetectors <<
"\n"
428 <<
"Minimize PeakLoc-" << peakOpt <<
" = " << s->fval <<
"\n";
430 g_log.
information() <<
"Move (X) = " << gsl_vector_get(s->x, 0) * 0.01 <<
" \n";
431 g_log.
information() <<
"Move (Y) = " << gsl_vector_get(s->x, 1) * 0.01 <<
" \n";
432 g_log.
information() <<
"Move (Z) = " << gsl_vector_get(s->x, 2) * 0.01 <<
" \n";
438 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);
439 const auto grid = componentInfo.pixelGridComponent(bankIndex);
440 Kernel::V3D Center = componentInfo.position(bankIndex) + CalCenter;
441 int pixmax = grid.nX - 1;
442 int pixmid = (grid.nY - 1) / 2;
443 BoundingBox box = componentInfo.boundingBox(componentInfo.detectorIndexAtXYZ(bankIndex, pixmax, pixmid, 0));
444 double baseX = box.
xMax();
445 double baseY = box.
yMax();
446 double baseZ = box.
zMax();
448 pixmid = (grid.nX - 1) / 2;
449 pixmax = grid.nY - 1;
450 box = componentInfo.boundingBox(componentInfo.detectorIndexAtXYZ(bankIndex, pixmid, pixmax, 0));
451 double upX = box.
xMax();
452 double upY = box.
yMax();
453 double upZ = box.
zMax();
462 double angle = gsl_vector_get(s->x, 3) *
deg2rad;
463 Base =
V3D(baseX, baseY * cos(angle) - baseZ * sin(angle), baseY * sin(angle) + baseZ * cos(angle));
467 Up =
V3D(upX, upY * cos(angle) - upZ * sin(angle), upY * sin(angle) + upZ * cos(angle));
472 angle = gsl_vector_get(s->x, 4) *
deg2rad;
473 Base =
V3D(baseZ * sin(angle) + baseX * cos(angle), baseY, baseZ * cos(angle) - baseX * sin(angle));
477 Up =
V3D(upZ * cos(angle) - upX * sin(angle), upY, upZ * sin(angle) + upX * cos(angle));
482 angle = gsl_vector_get(s->x, 5) *
deg2rad;
483 Base =
V3D(baseX * cos(angle) - baseY * sin(angle), baseX * sin(angle) + baseY * cos(angle), baseZ);
487 Up =
V3D(upX * cos(angle) - upY * sin(angle), upX * sin(angle) + upY * cos(angle), upZ);
492 outfile <<
"5 " << bankName.substr(4) <<
" " << grid.nX <<
" " << grid.nY <<
" "
493 << 100.0 * (grid.nX * grid.xStep) <<
" " << 100.0 * (grid.nY * grid.yStep) <<
" "
495 <<
" " << Center.
norm() <<
" ";
496 Center.
write(outfile);
506 gsl_multimin_fminimizer_free(s);
509 AnalysisDataService::Instance().remove(groupWSName);