cctw  0.2.1
cctwapplication.cpp
Go to the documentation of this file.
1 #include "cctwapplication.h"
3 #include "cctwtransformer.h"
4 #include <QScriptValue>
5 #include "cctwscriptengine.h"
6 #include "qcepproperty.h"
7 #include "cctwdebug.h"
8 #include "qcepsettingssaver.h"
9 #include <QtConcurrentRun>
10 #include <QFile>
14 #include "cctwunitcellproperty.h"
15 #include "cctwthread.h"
16 #include "cctwdatachunk.h"
17 
18 #ifdef WANT_IMPORT_COMMANDS
19 #include "qcepimagedataformatcbf.h"
20 #include "qcepimagedataformatmar345.h"
21 #include "qcepimagedataformattiff.h"
22 #endif
23 
24 #include <hdf5.h>
25 #include "lzf_filter.h"
26 
27 #ifdef Q_OS_UNIX
28 #include "getopt.h"
29 #endif
30 
31 QcepSettingsSaverPtr g_Saver;
32 
33 #ifdef WANT_IMPORT_COMMANDS
34 QcepImageDataFormatCBF<double> cbfImg("cbf");
35 QcepImageDataFormatTiff<double> tiffImg("tiff");
36 QcepImageDataFormatMar345<double> mar345Img("mar345");
37 #endif
38 
39 enum {
41  MergeMode = 2,
42  NormMode = 3,
44 };
45 
46 CctwApplication::CctwApplication(int &argc, char *argv[])
47 #ifdef NO_GUI
48  : QCoreApplication(argc, argv),
49 #else
50  : QApplication(argc, argv),
51 #endif
52  m_ObjectNamer(this, "cctw"),
53 #ifndef NO_GUI
54  m_Window(NULL),
55 #endif
56  m_Parameters(NULL),
57 #ifdef WANT_IMPORT_COMMANDS
58  m_ImportData(NULL),
59 #endif
60  m_CompareData(NULL),
61  m_InputData(NULL),
62  m_OutputData(NULL),
63  m_Transform(NULL),
64  m_Transformer(NULL),
65  m_ScriptEngine(NULL),
66  m_PEIngressCommand(NULL),
67 #ifdef NO_GUI
68  m_Saver(NULL),
69 #else
70  m_Saver(new QcepSettingsSaver(this)),
71 #endif
72  m_GuiWanted(QcepSettingsSaverWPtr(), this, "guiWanted", true, "Is GUI wanted?"),
73  m_Mode(QcepSettingsSaverWPtr(), this, "mode", 0, "Operation mode"),
74  m_StartupCommands(QcepSettingsSaverWPtr(), this, "startupCommands", QcepStringList(), "Startup commands"),
75  m_InputFiles(QcepSettingsSaverWPtr(), this, "inputFiles", QcepStringList(), "Input files"),
76  m_OutputFile(QcepSettingsSaverWPtr(), this, "outputFile", "", "Output file"),
77  m_MaskFile(QcepSettingsSaverWPtr(), this, "maskFile", "", "Mask file"),
78  m_AnglesFile(QcepSettingsSaverWPtr(), this, "anglesFile", "", "Angles File"),
79  m_WeightsFile(QcepSettingsSaverWPtr(), this, "weightsFile", "", "Weights File"),
80  m_Debug(m_Saver, this, "debug", 0, "Debug Level"),
81  m_Halting(QcepSettingsSaverWPtr(), this, "halting", false, "Set to halt operation in progress"),
82  m_Progress(QcepSettingsSaverWPtr(), this, "progress", 0, "Progress completed"),
83  m_ProgressLimit(QcepSettingsSaverWPtr(), this, "progressLimit", 100, "Progress limit"),
84  m_DependenciesPath(m_Saver, this, "dependenciesPath", "", "Dependencies saved in"),
85  m_SettingsPath(m_Saver, this, "settingsPath", "", "Settings saved in"),
86  m_ScriptPath(m_Saver, this, "scriptPath", "", "Execute script from"),
87  m_SpecDataFilePath(m_Saver, this, "specDataFilePath", "", "Pathname of spec data file"),
88  m_MpiRank(QcepSettingsSaverWPtr(), this, "mpiRank", 0, "MPI Rank of process"),
89  m_MpiSize(QcepSettingsSaverWPtr(), this, "mpiSize", -1, "MPI Size"),
90  m_Verbosity(QcepSettingsSaverWPtr(), this, "verbosity", 0, "Output Verbosity"),
91  m_ExitStatus(QcepSettingsSaverWPtr(), this, "exitStatus", 0, "Exit Status")
92 {
93  QcepProperty::registerMetaTypes();
98 
99  g_Saver = m_Saver;
100 
101  connect(prop_Debug(), SIGNAL(valueChanged(int,int)), this, SLOT(onDebugChanged(int)));
102  connect(prop_Progress(), SIGNAL(valueChanged(int,int)), this, SLOT(onProgress(int)));
103 
104  connect(this, SIGNAL(aboutToQuit()), this, SLOT(doAboutToQuit()));
105 
106  register_lzf();
107 }
108 
109 QcepSettingsSaverWPtr CctwApplication::saver() const
110 {
111  return m_Saver;
112 }
113 
115 {
116  if (g_DebugLevel) {
117  g_DebugLevel->setDebugLevel(dbg);
118  }
119 }
120 
122 {
123  int prog = (prg*100)/get_ProgressLimit();
124 
125  if (m_LastProgress.fetchAndStoreOrdered(prog) != prog) {
126 #ifdef NO_GUI
127  if ((prog % 5 == 0)) {
128 // printMessage(tr("%1% completed").arg(prog));
129  printf("\r%d%% completed", prog);
130  fflush(stdout);
131  if (prog==100) {
132  printf("\n");
133  fflush(stdout);
134  }
135  }
136 #else
137  if (m_Window == NULL && (prog % 5 == 0)) {
138  printMessage(tr("%1% completed").arg(prog));
139  }
140 #endif
141  }
142 }
143 
144 void CctwApplication::decodeCommandLineArgs(int &argc, char *argv[])
145 {
146 #ifdef Q_OS_UNIX
147  decodeCommandLineArgsForUnix(argc, argv);
148 #endif
149 
150 #ifdef Q_OS_WIN
152 #endif
153 }
154 
156 {
157  prop_StartupCommands()->appendValue(cmd);
158 }
159 
160 QString CctwApplication::addSlashes(QString str)
161 {
162 
163  QString newStr;
164 
165  for(int i=0;i<str.length();i++) {
166  if(str[i] == '\0') {
167  newStr.append('\\');
168  newStr.append('0');
169  } else if(str[i] == '\'') {
170  newStr.append('\\');
171  newStr.append('\'');
172  } else if(str[i] == '\"') {
173  newStr.append('\\');
174  newStr.append('\"');
175  } else if(str[i] == '\\') {
176  newStr.append('\\');
177  newStr.append('\\');
178  } else {
179  newStr.append(str[i]);
180  }
181  }
182 
183  return newStr;
184 }
185 
187 {
188 #ifdef Q_OS_UNIX
189  int c;
190 
191  enum {
192  argInputChunks = 10,
193  argVersion,
194  argInputDataset,
195  argOutputDims,
196  argOutputChunks,
197  argOutputDataset,
198  argInputProject,
199  argOutputProject,
200  argProjectOutput,
201  argMergeInput,
202  argMergeOutput,
203  argOmega,
204  argTwoTheta,
205  argPhi,
206  argChi
207  };
208 
209  int option_index = 0;
210 
211  while (1) {
212  static struct option long_options[] = {
213  {"help", no_argument, 0, 'h'},
214  {"version", no_argument, 0, argVersion},
215  {"verbosity", optional_argument, 0, 'v'},
216  {"threads", required_argument, 0, 'j'},
217  {"input", required_argument, 0, 'i'},
218  {"inputchunks", required_argument, 0, argInputChunks},
219  {"inputdataset", required_argument, 0, argInputDataset},
220  {"mask", required_argument, 0, 'm'},
221  {"angles", required_argument, 0, 'a'},
222  {"omega", required_argument, 0, argOmega},
223  {"twotheta", required_argument, 0, argTwoTheta},
224  {"phi", required_argument, 0, argPhi},
225  {"chi", required_argument, 0, argChi},
226  {"weights", required_argument, 0, 'w'},
227  {"output", required_argument, 0, 'o'},
228  {"outputdims", required_argument, 0, argOutputDims},
229  {"outputchunks", required_argument, 0, argOutputChunks},
230  {"outputdataset", required_argument, 0, argOutputDataset},
231  {"normalization", required_argument, 0, 'N'},
232  {"compression", required_argument, 0, 'z'},
233  {"subset", required_argument, 0, 'S'},
234  {"transform", no_argument, 0, 't'},
235  {"depends", no_argument, 0, 'd'},
236  {"nodepends", no_argument, 0, 'x'},
237  {"debug", required_argument, 0, 'D'},
238  {"preferences", required_argument, 0, 'p'},
239  {"gui", no_argument, 0, 'g'},
240  {"nogui", no_argument, 0, 'n'},
241  {"command", required_argument, 0, 'c'},
242  {"script", required_argument, 0, 's'},
243  {"iproject", optional_argument, 0, argInputProject},
244  {"oproject", optional_argument, 0, argOutputProject},
245  {"projectout", required_argument, 0, argProjectOutput},
246  {"mergein", required_argument, 0, argMergeInput},
247  {"mergeout", required_argument, 0, argMergeOutput},
248  {0,0,0,0}
249  };
250 
251  c = getopt_long(argc, argv, "hv::j:i:m:a:o:N:S:tdxD:p:gnc:w::s:z:", long_options, &option_index);
252 
253  if (c == -1) {
254  break;
255  }
256 
257  switch (c) {
258  case 'h':
259  startupCommand("showHelp();");
260  break;
261 
262  case argVersion:
263  startupCommand("showVersion();");
264  break;
265 
266  case 'v':
267  if (optarg) {
268  set_Verbosity(atoi(optarg));
269  } else {
270  prop_Verbosity()->incValue(1);
271  }
272  break;
273 
274  case 'j':
275  startupCommand(tr("setThreads(\"%1\");").arg(addSlashes(optarg)));
276  break;
277 
278  case 'i':
279  pushInputFile(optarg);
280  break;
281 
282  case argInputChunks:
283  startupCommand(tr("setInputChunks(\"%1\");").arg(addSlashes(optarg)));
284  break;
285 
286  case argInputDataset:
287  startupCommand(tr("setInputDataset(\"%1\");").arg(addSlashes(optarg)));
288  break;
289 
290  case 'm':
291  startupCommand(tr("setMask(\"%1\");").arg(addSlashes(optarg)));
292  break;
293 
294  case 'a':
295  startupCommand(tr("setAngles(\"%1\");").arg(addSlashes(optarg)));
296  break;
297 
298  case argOmega:
299  startupCommand(tr("setOmega(\"%1\");").arg(addSlashes(optarg)));
300  break;
301 
302  case argTwoTheta:
303  startupCommand(tr("setTwoTheta(\"%1\");").arg(addSlashes(optarg)));
304  break;
305 
306  case argPhi:
307  startupCommand(tr("setPhi(\"%1\");").arg(addSlashes(optarg)));
308  break;
309 
310  case argChi:
311  startupCommand(tr("setChi(\"%1\");").arg(addSlashes(optarg)));
312  break;
313 
314  case 'w':
315  startupCommand(tr("setWeights(\"%1\");").arg(addSlashes(optarg)));
316  break;
317 
318  case 'o':
319  set_OutputFile(optarg);
320  break;
321 
322  case 'S':
323  startupCommand(tr("setSubset(\"%1\");").arg(addSlashes(optarg)));
324  break;
325 
326  case argOutputDims:
327  startupCommand(tr("setOutputDims(\"%1\");").arg(addSlashes(optarg)));
328  break;
329 
330  case argOutputChunks:
331  startupCommand(tr("setOutputChunks(\"%1\");").arg(addSlashes(optarg)));
332  break;
333 
334  case argOutputDataset:
335  startupCommand(tr("setOutputDataset(\"%1\");").arg(addSlashes(optarg)));
336  break;
337 
338  case 't':
339  startupCommand(tr("doTransform(\"%1\");").arg(addSlashes(optarg)));
340  break;
341 
342  case 'd':
343  startupCommand(tr("partialDependencies(\"%1\");").arg(addSlashes(optarg)));
344  break;
345 
346  case 'x':
347  startupCommand(tr("noDependencies();"));
348  break;
349 
350  case 'N':
351  startupCommand(tr("normalization(\"%1\");").arg(addSlashes(optarg)));
352  break;
353 
354  case 'z':
355  startupCommand(tr("compression(\"%1\");").arg(addSlashes(optarg)));
356  break;
357 
358  case argInputProject:
359  startupCommand(tr("inputProject(%1);").arg(optarg?atoi(optarg):7));
360  break;
361 
362  case argOutputProject:
363  startupCommand(tr("outputProject(%1);").arg(optarg?atoi(optarg):7));
364  break;
365 
366  case argProjectOutput:
367  startupCommand(tr("setProjectOutput(\"%1\");").arg(addSlashes(optarg)));
368  break;
369 
370  case 'g': /* want gui */
371  set_GuiWanted(true);
372  break;
373 
374  case 'n': /* no gui */
375  set_GuiWanted(false);
376  break;
377 
378  case 'c': /* command line command */
379  startupCommand(tr("%1;").arg(optarg));
380  break;
381 
382  case 's': /* script file */
383  startupCommand(tr("executeScriptFile(\"%1\");").arg(addSlashes(optarg)));
384  break;
385 
386  case 'p': /* preferences file */
387  startupCommand(tr("loadPreferences(\"%1\");").arg(addSlashes(optarg)));
388  break;
389 
390  case argMergeInput:
391  pushInputFile(optarg);
392  break;
393 
394  case argMergeOutput:
395  set_OutputFile(optarg);
396  break;
397 
398  case 'D': /* change debug level */
399  {
400  char *a = optarg;
401  int lvl = atoi(a);
402  set_Debug(lvl);
403  }
404  break;
405 
406  case '?': /* unknown option, or missing optional argument */
407  printMessage("Unrecognized command line option");
408  break;
409 
410  default:
411  break;
412  }
413  }
414 
415  int first=true;
416 
417  while (optind < argc) {
418  if (first) {
419  first = false;
420 
421  if (strcasecmp(argv[optind], "transform") == 0) {
422  set_Mode(TransformMode);
423  } else if (strcasecmp(argv[optind], "merge") == 0) {
424  set_Mode(MergeMode);
425  } else if (strcasecmp(argv[optind], "norm") == 0) {
426  set_Mode(NormMode);
427  } else if (strcasecmp(argv[optind], "project") == 0) {
428  set_Mode(ProjectMode);
429  } else {
430  pushInputFile(argv[optind]);
431  }
432  } else {
433  pushInputFile(argv[optind]);
434  }
435 
436  optind++;
437  }
438 #endif
439 }
440 
442 {
443 }
444 
445 static herr_t cctwH5print(unsigned n, const H5E_error2_t *eptr, void *data)
446 {
447  CctwApplication *app = (CctwApplication*) data;
448 
449  if (app) {
450  app->printMessage(QObject::tr("%1:%2 : %3").arg(eptr->file_name).arg(eptr->line).arg(eptr->desc));
451  }
452 
453  return 0;
454 }
455 
457 {
458  printMessage("HDF5 Error occurred");
459 
460  H5Ewalk(H5E_DEFAULT, H5E_WALK_DOWNWARD, &cctwH5print, this);
461 }
462 
463 static herr_t cctwH5error(hid_t h, void *data)
464 {
465  CctwApplication *app = (CctwApplication*) data;
466 
467  if (app) {
468  app->printHDF5errors();
469  }
470 
471  return 0;
472 }
473 
475 {
476  H5Eset_auto(H5E_DEFAULT, &cctwH5error, (void*) this);
477 }
478 
479 void CctwApplication::initialize(int &argc, char *argv[])
480 {
482 
483  decodeCommandLineArgs(argc, argv);
484 
485 #ifdef WANT_IMPORT_COMMANDS
486  m_ImportData = new CctwImporter(this, "importData", this);
487 #endif
488 
489  m_CompareData = new CctwComparer(this, "compareData", this);
490 
491  m_Parameters = new CctwCrystalCoordinateParameters("parameters", this);
492 
493  m_InputData = new CctwChunkedData(this,
494  CctwIntVector3D(256,256,256),
495  CctwIntVector3D(32, 32, 32),
496  true,
497  "inputData",
498  this);
499  m_InputData -> allocateChunks();
500 
501  m_OutputData = new CctwChunkedData(this,
502  CctwIntVector3D(256,256,256),
503  CctwIntVector3D(32, 32, 32),
504  false,
505  "outputData",
506  this);
507  m_OutputData -> allocateChunks();
508 
509  m_Transform = new CctwCrystalCoordinateTransform(m_Parameters, "transform", NULL, this);
510 
511  m_Transformer = new CctwTransformer(this,
512  m_InputData,
513  m_OutputData,
514  m_Transform, /*1, 1, 1,*/
515  "transformer",
516  this);
517 
518  m_PEIngressCommand = new CctwPEIngressCommand(this, "peingress", this);
519 
520  m_ScriptEngine = new CctwScriptEngine(this, this);
521 
522 #ifdef WANT_IMPORT_COMMANDS
523  m_ScriptEngine->globalObject().setProperty("importData", m_ScriptEngine->newQObject(m_ImportData));
524 #endif
525 
526  m_ScriptEngine->globalObject().setProperty("compareData", m_ScriptEngine->newQObject(m_CompareData));
527  m_ScriptEngine->globalObject().setProperty("inputData", m_ScriptEngine->newQObject(m_InputData));
528  m_ScriptEngine->globalObject().setProperty("outputData", m_ScriptEngine->newQObject(m_OutputData));
529  m_ScriptEngine->globalObject().setProperty("parameters", m_ScriptEngine->newQObject(m_Parameters));
530  m_ScriptEngine->globalObject().setProperty("transform", m_ScriptEngine->newQObject(m_Transform));
531  m_ScriptEngine->globalObject().setProperty("transformer", m_ScriptEngine->newQObject(m_Transformer));
532  m_ScriptEngine->globalObject().setProperty("peingress", m_ScriptEngine->newQObject(m_PEIngressCommand));
533  m_ScriptEngine->globalObject().setProperty("application", m_ScriptEngine->newQObject(this));
534  m_ScriptEngine->globalObject().setProperty("globals", m_ScriptEngine->globalObject());
535 
536 #ifndef NO_GUI
537  readSettings();
538 #endif
539 
540  if (m_Saver) {
541  m_Saver->start();
542  }
543 
544 #ifdef NO_GUI
545  set_GuiWanted(false);
546 #else
547  if (get_GuiWanted()) {
548  m_Window = new CctwqtMainWindow(this);
549  }
550 
551  if (m_Window) {
552  m_Window->show();
553  }
554 #endif
555 
556  preStartup();
557 
558  foreach(QString cmd, get_StartupCommands()) {
559  QMetaObject::invokeMethod(this, "evaluateStartupCommand", Qt::QueuedConnection, Q_ARG(QString, cmd));
560  }
561 
562  postStartup();
563 
564  if (!get_GuiWanted()) {
565  QMetaObject::invokeMethod(this, "execute", Qt::QueuedConnection);
566  QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection);
567  }
568 }
569 
571 {
572 #ifndef NO_GUI
573  writeSettings();
574 #endif
575 }
576 
577 void CctwApplication::printLine(QString msg)
578 {
579 #ifdef NO_GUI
580  printf("%s\n", qPrintable(msg));
581 #else
582  if (m_Window) {
583  m_Window->printLine(msg);
584  } else {
585  printf("%s\n", qPrintable(msg));
586  }
587 #endif
588 }
589 
590 void CctwApplication::printMessage(QString msg, QDateTime dt)
591 {
592 #ifdef NO_GUI
593  printf("%s\n", qPrintable(msg));
594  fflush(stdout);
595 #else
596  if (m_Window) {
597  m_Window->printMessage(msg, dt);
598  } else {
599  printf("%s\n", qPrintable(msg));
600  }
601 #endif
602 }
603 
604 void CctwApplication::wait(QString msg)
605 {
606  waitCompleted();
607 
608 // printMessage(tr("Wait: %1").arg(msg));
609 }
610 
612 {
613  if (m_ScriptEngine) {
614  QScriptValue val = m_ScriptEngine->evaluate(cmd);
615 
617 
618  if (!val.isUndefined()) {
619  printMessage(tr("%1").arg(val.toString()));
620  }
621  }
622 }
623 
625 {
626  if (m_ScriptEngine) {
627  QScriptValue val = m_ScriptEngine->evaluate(cmd);
628 
630 
631  if (val.isUndefined()) {
632  printMessage(tr("%1").arg(cmd));
633  } else {
634  printMessage(tr("%1 -> %2").arg(cmd).arg(val.toString()));
635  }
636  }
637 }
638 
639 QScriptValue CctwApplication::evaluate(QString cmd)
640 {
641  if (m_ScriptEngine) {
642  QScriptValue result = m_ScriptEngine->evaluate(cmd);
643 
645 
646  return result;
647  } else {
648  return QScriptValue();
649  }
650 }
651 
653 {
654  if (m_ScriptEngine) {
655  QFile f(path);
656 
657  if (f.open(QIODevice::ReadOnly)) {
658  QString script = f.readAll();
659 
660  QScriptValue val = m_ScriptEngine->evaluate(script, path, 1);
661 
663 
664  printMessage(tr("Result -> %1").arg(val.toString()));
665  }
666  }
667 }
668 
669 void CctwApplication::showHelp(QString about)
670 {
671  printLine(tr(
672  "\n"
673  "usage: %1 transform|merge|norm|project <inputs> <options>\n"
674  "\n"
675  "where inputs are one or more hdf dataset refs (in url format)\n"
676  "the file part of the URL gives the hdf/nexus file, and the 'fragment'\n"
677  "(separated by a # character) gives the hdf dataset path\n"
678  "\n"
679  "where options are:\n"
680  "\n"
681  "--help, -h display this text\n"
682  "--version display version info\n"
683  "--verbosity[=n], -v[=n] set verbosity to 'n', or increment it if 'n' not given\n"
684  "--threads <n>, -j <n> set number of worker threads\n"
685  "--input <f>, -i <f> specify input data (url format)\n"
686  "--inputchunks <cks> specify input chunk size (e.g. 32x32x32 or 32)\n"
687  "--inputdataset <dsn> specify input dataset path\n"
688  "--mask <f>, -m <f> specify mask data (url format)\n"
689  "--maskdataset <dsn> specify mask dataset path\n"
690  "--angles <f>, -a <f> specify angles data (url format\n"
691  "--anglesdataset <f> specify angles dataset path\n"
692  "--omega <angs> specify omega angles (url-angles format\n"
693  "--twotheta <angs> specify two theta angles (url-angles format\n"
694  "--chi <angs> specify chi angles (url-angles format\n"
695  "--phi <angs> specify phi angles (url-angles format\n"
696  "--weights <f>, -w <f> specify weights data (url format)\n"
697  "--output <f>, -o <f> specify output data (url format)\n"
698  "--outputdims <dims> specify output dimensions (e.g. 2048x2048x2048 or 2048)\n"
699  "--outputchunks <cks> specify output chunk size (e.g. 32x32x32 or 32)\n"
700  "--outputdataset <dsn> specify output dataset path\n"
701  "--normalization <n>, -N <n> normalize output file(s) (0=no norm, 1=norm)\n"
702  "--compression <n>, -z <n> compress output files (-ve = LZF, 0 = none, 1-9 = GZIP\n"
703  "--subset <n/m>, -S <n/m> specify subset of input data to operate on (or all if blank)\n"
704  "--transform, -t transform all or part of the data\n"
705  "--depends, -d calculate dependencies for all or part of the data\n"
706  "--nodepends, -x clear dependencies\n"
707  "--debug <n>, -D <n> set debug level\n"
708  "--preferences <f>, -p <f> read settings from file <f>\n"
709  "--gui, -g use GUI interface if available\n"
710  "--nogui, -n no GUI interface\n"
711  "--command <cmd>, -c <cmd> execute command <cmd>\n"
712  "--script <f>, -s <f> run script in file <f>\n"
713  "--iproject {=n} project input dataset (along x=1,y=2,z=4 axes)\n"
714  "--oproject {=n} project output dataset (along x=1,y=2,z=4 axes)\n"
715  "--projectout <p> prefix for projected output files (add .x.tif, .y.tif or .z.tif)\n"
716  "--mergein <f> specify an input dataset to merge (url format)\n"
717  "--mergeout <f> merge (previously specified) datasets into output (url format)\n"
718  "\n"
719  "Where <angs> may be:\n"
720  "A single numeric value set the angle to the given value\n"
721  "A comma separated number pair set starting angle and step\n"
722 // "A ref to an HDF scalar value set the angle to the value\n"
723 // "A ref to an HDF group containing 'start' and 'step' - set start and step accordingly\n"
724  "A ref to an HDF array set angles to values from array\n"
725  "\n"
726  "Examples:\n"
727  "cctwcli transform file1.nxs\\#/data/entry/v -o xform.nxs\\#/data/entry/v\n"
728  "cctwcli merge file1.nxs\\#/data/entry/v file2.nxs\\#/data/entry/v -o merge.nxs\\#/data/entry/v\n"
729  ).arg(arguments().at(0)));
730 }
731 
733 {
734  printLine(tr("cctw version " STR(CCTW_VERSION)));
735  printLine(tr("qt version %1").arg(qVersion()));
736  printLine(tr("ceplib version " STR(QCEPLIB_VERSION)));
737  printLine(tr("hdf5 version " STR(QCEPLIB_HDF5_VERSION)));
738 #ifndef NO_GUI
739  printLine(tr("qwt version " STR(QCEPLIB_QWT_VERSION)));
740 #endif
741  printLine(tr("tiff version " STR(QCEPLIB_TIFF_VERSION)));
742  printLine(tr("cbf version " STR(QCEPLIB_CBF_VERSION)));
743 }
744 
745 void CctwApplication::setThreads(QString desc)
746 {
747  printMessage(tr("Set number of pool threads to %1").arg(desc));
748 
749  bool ok;
750 
751  int n = desc.toInt(&ok);
752 
753  if (ok) {
754  if (n == 0) {
755  QThreadPool::globalInstance()->setMaxThreadCount(QThread::idealThreadCount());
756  } else {
757  QThreadPool::globalInstance()->setMaxThreadCount(n);
758  }
759  }
760 }
761 
763 {
764  if (m_InputData) {
765  printMessage(tr("Set input data to %1").arg(data));
766 
767  m_InputData->setDataSource(data);
768  }
769 }
770 
772 {
773  if (m_InputData) {
774  printMessage(tr("Set input chunk size to %1").arg(data));
775 
776  m_InputData->setChunks(data);
777  }
778 }
779 
781 {
782  if (m_InputData) {
783  printMessage(tr("Set input data set name to %1").arg(data));
784 
785  m_InputData->setDataset(data);
786  }
787 }
788 
790 {
791  if (m_InputData) {
792  printMessage(tr("Set mask to %1").arg(data));
793 
794  set_MaskFile(data);
795  }
796 }
797 
799 {
800  if (m_InputData) {
801  printMessage(tr("Set mask dataset to %1").arg(data));
802 
804  }
805 }
806 
808 {
809  prop_InputFiles()->appendValue(path);
810 }
811 
813 {
814  if (m_InputData) {
815  printMessage(tr("Set Angles to %1").arg(data));
816 
818  }
819 }
820 
822 {
823  if (m_InputData) {
824  printMessage(tr("Set Angles dataset to %1").arg(data));
825 
827  }
828 }
829 
831 {
832  if (m_OutputData) {
833  printMessage(tr("Set output data to %1").arg(data));
834 
836  }
837 }
838 
840 {
841  if (m_OutputData) {
842  printMessage(tr("Set output dataset dimensions to %1").arg(data));
843 
844  m_OutputData->setDims(data);
845  }
846 }
847 
849 {
850  if (m_OutputData) {
851  printMessage(tr("Set output chunk size to %1").arg(data));
852 
853  m_OutputData->setChunks(data);
854  }
855 }
856 
858 {
859  if (m_OutputData) {
860  printMessage(tr("Set output data set name to %1").arg(data));
861 
862  m_OutputData->setDataset(data);
863  }
864 }
865 
866 void CctwApplication::setSubset(QString desc)
867 {
868  if (m_Transformer) {
869  m_Transformer->set_Subset(desc);
870  }
871 }
872 
873 void CctwApplication::transform(QString desc)
874 {
875 // printMessage(tr("Partial transform of %1").arg(desc));
876 
877  if (m_Transformer) {
878  if (m_Transformer->get_UseDependencies()) {
880  } else {
882  }
883  }
884 }
885 
886 void CctwApplication::setOmega(QString data)
887 {
888  if(m_Parameters) {
889  printMessage(tr("Set Omega Values to %1").arg(data));
890 
891  m_Parameters->setOmega(data);
892  }
893 }
894 
896 {
897  if(m_Parameters) {
898  printMessage(tr("Set Two Theta Values to %1").arg(data));
899 
900  m_Parameters->setTwoTheta(data);
901  }
902 }
903 
904 void CctwApplication::setPhi(QString data)
905 {
906  if(m_Parameters) {
907  printMessage(tr("Set Phi Values to %1").arg(data));
908 
909  m_Parameters->setPhi(data);
910  }
911 }
912 
913 void CctwApplication::setChi(QString data)
914 {
915  if(m_Parameters) {
916  printMessage(tr("Set Chi Values to %1").arg(data));
917 
918  m_Parameters->setChi(data);
919  }
920 }
921 
922 //void CctwApplication::transform()
923 //{
924 // QVector < QFuture < void > > futures;
925 // waitCompleted();
926 
927 // CctwIntVector3D chunks = m_InputData->chunkCount();
928 
929 // set_Halting(false);
930 // set_Progress(0);
931 // set_ProgressLimit(chunks.volume());
932 
933 // QTime startAt;
934 
935 // startAt.start();
936 
937 // printMessage("Starting Transform");
938 
939 // m_InputData -> beginTransform(true, 0);
940 // m_OutputData -> beginTransform(false, 0);
941 
942 // for (int z=0; z<chunks.z(); z++) {
943 // for (int y=0; y<chunks.y(); y++) {
944 // for (int x=0; x<chunks.x(); x++) {
945 // if (get_Halting()) {
946 // goto abort;
947 // } else {
948 // CctwIntVector3D idx(x,y,z);
949 
950 // int n = m_InputData->chunkNumberFromIndex(idx);
951 
952 // addWorkOutstanding(1);
953 
954 // futures.append(
955 // QtConcurrent::run(m_Transformer, &CctwTransformer::runTransformChunkNumber, n));
956 // }
957 // }
958 // }
959 // }
960 
961 //abort:
962 // foreach (QFuture<void> f, futures) {
963 // f.waitForFinished();
964 // processEvents();
965 // }
966 
967 // int msec = startAt.elapsed();
968 
969 // m_OutputData -> flushOutputFile();
970 
971 // m_InputData -> endTransform();
972 // m_OutputData -> endTransform();
973 
974 // printMessage(tr("Transform complete after %1 msec, %2 chunks still allocated")
975 // .arg(msec)
976 // .arg(CctwDataChunk::allocatedChunkCount()));
977 //}
978 
980 {
981 // printMessage(tr("Partial dependencies of %1").arg(desc));
982 
984 }
985 
987 {
988  if (m_Transformer) {
990  }
991 }
992 
994 {
995  QSettings settings("xray.aps.anl.gov", "cctw");
996 
997  readSettings(&settings);
998 }
999 
1001 {
1002  QSettings settings(path, QSettings::IniFormat);
1003 
1004  printMessage(tr("Reading settings from %1").arg(path));
1005 
1006  readSettings(&settings);
1007 }
1008 
1009 void CctwApplication::readSettings(QSettings *settings)
1010 {
1011  QcepProperty::readSettings(this, &staticMetaObject, "cctw", settings, true);
1012 
1013  if (m_Parameters) {
1014  m_Parameters->readSettings(settings, "parameters");
1015  }
1016 
1017 #ifdef WANT_IMPORT_COMMANDS
1018  if (m_ImportData) {
1019  m_ImportData->readSettings(settings, "importData");
1020  }
1021 #endif
1022 
1023  if (m_CompareData) {
1024  m_CompareData->readSettings(settings, "compareData");
1025  }
1026 
1027  if (m_InputData) {
1028  m_InputData->readSettings(settings, "inputData");
1029  }
1030 
1031  if (m_OutputData) {
1032  m_OutputData->readSettings(settings, "outputData");
1033  }
1034 
1035  if (m_Transform) {
1036  m_Transform->readSettings(settings, "transform");
1037  }
1038 
1039  if (m_Transformer) {
1040  m_Transformer->readSettings(settings, "transformer");
1041  }
1042 
1043  if (m_PEIngressCommand) {
1044  m_PEIngressCommand->readSettings(settings, "peingress");
1045  }
1046 }
1047 
1049 {
1050  QSettings settings("xray.aps.anl.gov", "cctw");
1051 
1052  printMessage(tr("Writing default settings"));
1053 
1054  writeSettings(&settings);
1055 }
1056 
1058 {
1059  QSettings settings("xray.aps.anl.gov", "cctw");
1060 
1061  printMessage(tr("Writing default settings"));
1062 
1063  settings.clear();
1064 
1065  writeSettings(&settings);
1066 }
1067 
1069 {
1070  QSettings settings(path, QSettings::IniFormat);
1071 
1072  printMessage(tr("Writing settings to %1").arg(path));
1073 
1074  writeSettings(&settings);
1075 }
1076 
1077 void CctwApplication::writeSettings(QSettings *settings)
1078 {
1079  QcepProperty::writeSettings(this, &staticMetaObject, "cctw", settings, true);
1080 
1081  if (m_Parameters) {
1082  m_Parameters->writeSettings(settings, "parameters");
1083  }
1084 
1085 #ifdef WANT_IMPORT_COMMANDS
1086  if (m_ImportData) {
1087  m_ImportData->writeSettings(settings, "importData");
1088  }
1089 #endif
1090 
1091  if (m_CompareData) {
1092  m_CompareData->writeSettings(settings, "compareData");
1093  }
1094 
1095  if (m_InputData) {
1096  m_InputData->writeSettings(settings, "inputData");
1097  }
1098 
1099  if (m_OutputData) {
1100  m_OutputData->writeSettings(settings, "outputData");
1101  }
1102 
1103  if (m_Transform) {
1104  m_Transform->writeSettings(settings, "transform");
1105  }
1106 
1107  if (m_Transformer) {
1108  m_Transformer->writeSettings(settings, "transformer");
1109  }
1110 
1111  if (m_PEIngressCommand) {
1112  m_PEIngressCommand->writeSettings(settings, "peingress");
1113  }
1114 }
1115 
1117 {
1118  QString res;
1119 
1120  if (m_Parameters) {
1121  res += m_Parameters->settingsScript();
1122  }
1123 
1124 // if (m_ImportData) {
1125 // res += m_ImportData->settingsScript();
1126 // }
1127 
1128 // if (m_CompareData) {
1129 // res += m_CompareData->settingsScript();
1130 // }
1131 
1132  if (m_InputData) {
1133  res += m_InputData->settingsScript();
1134  }
1135 
1136  if (m_OutputData) {
1137  res += m_OutputData->settingsScript();
1138  }
1139 
1140  if (m_Transform) {
1141  res += m_Transform->settingsScript();
1142  }
1143 
1144  if (m_Transformer) {
1145  res += m_Transformer->settingsScript();
1146  }
1147 
1148  if (m_PEIngressCommand) {
1150  }
1151 
1152  return res;
1153 }
1154 
1156 {
1157  if (!get_Halting()) {
1158  QcepDoubleVector anglesvec = m_InputData->get_Angles();
1159  double *angs = (anglesvec.count()<=0 ? NULL : anglesvec.data());
1160 
1161  CctwCrystalCoordinateTransform transform(m_Parameters, tr("transform-%1").arg(n), angs, NULL);
1162 
1163  // printMessage(tr("Calculate Chunk Dependencies for chunk [%1,%2,%3]").arg(idx.x()).arg(idx.y()).arg(idx.z()));
1164 
1165  CctwDataChunk *chunk = m_InputData->chunk(n);
1166 
1167  if (chunk) {
1168  CctwIntVector3D chStart = chunk->chunkStart();
1169  CctwIntVector3D chSize = chunk->chunkSize();
1170  CctwDoubleVector3D dblStart(chStart.x(), chStart.y(), chStart.z());
1171  int lastChunk = -1;
1172 
1173  int osx = m_Transformer->get_OversampleX();
1174  int osy = m_Transformer->get_OversampleY();
1175  int osz = m_Transformer->get_OversampleZ();
1176 
1177  double osxstp = osx >= 1 ? 1.0/osx : 0;
1178  double osystp = osy >= 1 ? 1.0/osy : 0;
1179  double oszstp = osz >= 1 ? 1.0/osz : 0;
1180 
1181  for (int z=0; z<chSize.z(); z++) {
1182  for (int oz=0; oz<osz; oz++) {
1183  for (int y=0; y<chSize.y(); y++) {
1184  for (int oy=0; oy<osy; oy++) {
1185  for (int x=0; x<chSize.x(); x++) {
1186  for (int ox=0; ox<osx; ox++) {
1187  CctwDoubleVector3D coords = dblStart+CctwDoubleVector3D(x+ox*osxstp, y+oy*osystp, z+oz*oszstp);
1188 
1189  CctwDoubleVector3D xfmcoord = transform.forward(coords);
1190 
1191  CctwIntVector3D pixels(xfmcoord);
1192 
1193  if (m_OutputData->containsPixel(pixels)) {
1194  int opchunk = m_OutputData->chunkContaining(pixels);
1195 
1196  if (opchunk != lastChunk) {
1197  lastChunk = opchunk;
1198  // m_InputData->addDependency(n, opchunk);
1199  // m_OutputData->addDependency(opchunk, n);
1200  m_Transformer->addDependency(n, opchunk);
1201  }
1202  }
1203  }
1204  }
1205  }
1206  }
1207  }
1208  }
1209  }
1210 
1211 // printMessage(tr("Finished Chunk Dependencies for chunk [%1,%2,%3]").arg(idx.x()).arg(idx.y()).arg(idx.z()));
1212 
1213  m_DependencyCounter.fetchAndAddOrdered(-1);
1214  } else {
1215  m_DependencyCounter.fetchAndStoreOrdered(0);
1216  }
1217 
1218  prop_Progress()->incValue(1);
1219 
1220  workCompleted(1);
1221 }
1222 
1224 {
1225  QVector < QFuture < void > > futures;
1226  waitCompleted();
1227 
1228 // m_InputData->clearDependencies();
1229 // m_OutputData->clearDependencies();
1230 
1232 
1234 
1235  set_Halting(false);
1236  set_Progress(0);
1237  set_ProgressLimit(chunks.volume());
1238 
1239  QTime startAt;
1240 
1241  startAt.start();
1242 
1243  printMessage("Starting calculate dependencies");
1244 
1245  m_DependencyCounter.fetchAndStoreOrdered(0);
1246 
1247  for (int z=0; z<chunks.z(); z++) {
1248  for (int y=0; y<chunks.y(); y++) {
1249  for (int x=0; x<chunks.x(); x++) {
1250 // while ((!get_Halting()) && (m_DependencyCounter.fetchAndAddOrdered(0) > 32)) {
1252 // processEvents();
1253 // }
1254 
1255  if (get_Halting()) {
1256  m_DependencyCounter.fetchAndStoreOrdered(0);
1257  goto abort;
1258  } else {
1259  CctwIntVector3D idx(x,y,z);
1260  int n = m_InputData->chunkNumberFromIndex(idx);
1261 
1262  m_DependencyCounter.fetchAndAddOrdered(1);
1263 
1264  addWorkOutstanding(1);
1265  futures.append(
1266  QtConcurrent::run(this, &CctwApplication::calculateChunkDependencies, n));
1267 // calculateChunkDependencies(idx);
1268  }
1269  }
1270  }
1271  }
1272 
1273 abort:
1274  while (m_DependencyCounter.fetchAndAddOrdered(0) > 0) {
1275  CctwThread::msleep(10);
1276  processEvents();
1277  }
1278 
1279  foreach (QFuture<void> f, futures) {
1280  f.waitForFinished();
1281  processEvents();
1282  }
1283 
1284 // m_Transformer -> completedDependencies();
1285 
1286  int msec = startAt.elapsed();
1287 
1288  printMessage(tr("finished calculate dependencies after %1 msec").arg(msec));
1289 }
1290 
1292 {
1293  if (m_Transformer) {
1295  }
1296 }
1297 
1299 {
1300  if (m_Transformer) {
1302  }
1303 }
1304 
1306 {
1308 
1309  set_Halting(false);
1310 
1311  printMessage(tr("Check mapping"));
1312 
1313  for (int n=0; n<chunks.volume(); n++) {
1314  if (get_Halting()) {
1315  break;
1316  } else {
1318  int nn = m_InputData->chunkNumberFromIndex(idx);
1319 
1320  if (nn != n) {
1321  printMessage(tr("Problem: %1 => [%2,%3,%4] => %5").arg(n).arg(idx.x()).arg(idx.y()).arg(idx.z()).arg(nn));
1322  }
1323  }
1324  }
1325 
1326  for (int z=0; z<chunks.z(); z++) {
1327  for (int y=0; y<chunks.y(); y++) {
1328  for (int x=0; x<chunks.x(); x++) {
1329  if (get_Halting()) {
1330  break;
1331  } else {
1332  CctwIntVector3D idx(x,y,z);
1333  int n = m_InputData->chunkNumberFromIndex(idx);
1335 
1336  if (idx != idx2) {
1337  printMessage(tr("Problem: [%1,%2,%3] => %4 => [%5,%6,%7]")
1338  .arg(idx.x()).arg(idx.y()).arg(idx.z())
1339  .arg(n)
1340  .arg(idx2.x()).arg(idx2.y()).arg(idx2.z()));
1341  }
1342  }
1343  }
1344  }
1345  }
1346 
1347  printMessage(tr("Input Data Dependencies"));
1348 
1349  for (int z=0; z<chunks.z(); z++) {
1350  for (int y=0; y<chunks.y(); y++) {
1351  for (int x=0; x<chunks.x(); x++) {
1352  if (get_Halting()) {
1353  break;
1354  } else {
1355  CctwIntVector3D idx(x,y,z);
1356 
1357  CctwDataChunk *chunk = m_InputData -> chunk(idx);
1358 
1359  if (chunk) {
1360  chunk->reportDependencies();
1361  }
1362  }
1363  }
1364  }
1365  }
1366 }
1367 
1369 {
1371 
1372  set_Halting(false);
1373  set_Progress(0);
1374  set_ProgressLimit(chunks.volume());
1375 
1376  for (int z=0; z<chunks.z(); z++) {
1377  for (int y=0; y<chunks.y(); y++) {
1378  for (int x=0; x<chunks.x(); x++) {
1379  if (get_Halting()) {
1380  break;
1381  } else {
1382  CctwIntVector3D idx(x,y,z);
1383 
1385  }
1386  }
1387  }
1388  }
1389 }
1390 
1392 {
1393  CctwDataChunk *chunk = m_OutputData->chunk(idx);
1394 
1395  if (chunk) {
1396  chunk->reportDependencies();
1397  }
1398 }
1399 
1401 {
1403 
1404  set_Halting(false);
1405  set_Progress(0);
1406  set_ProgressLimit(chunks.volume());
1407 
1408  for (int z=0; z<chunks.z(); z++) {
1409  for (int y=0; y<chunks.y(); y++) {
1410  for (int x=0; x<chunks.x(); x++) {
1411  if (get_Halting()) {
1412  break;
1413  } else {
1414  CctwIntVector3D idx(x,y,z);
1415 
1417  }
1418  }
1419  }
1420  }
1421 }
1422 
1424 {
1425  CctwDataChunk *chunk = m_InputData->chunk(idx);
1426 
1427  if (chunk) {
1428  chunk->reportDependencies();
1429  }
1430 }
1431 
1433 {
1435 
1436  set_Halting(false);
1437  set_Progress(0);
1438  set_ProgressLimit(chunks.volume());
1439 
1440  for (int z=0; z<chunks.z(); z++) {
1441  for (int y=0; y<chunks.y(); y++) {
1442  QString aLine;
1443 
1444  for (int x=0; x<chunks.x(); x++) {
1445  if (get_Halting()) {
1446  break;
1447  } else {
1448  CctwIntVector3D idx(x,y,z);
1449 
1450  CctwDataChunk *chunk = m_InputData->chunk(idx);
1451 
1452  if (chunk) {
1453  int nDeps = chunk->dependencyCount();
1454 
1455  if (nDeps > 9) {
1456  aLine += "*";
1457  } else if (nDeps >= 1) {
1458  aLine += tr("%1").arg(nDeps);
1459  } else {
1460  aLine += "0";
1461  }
1462  } else {
1463  aLine += "0";
1464  }
1465  }
1466  }
1467 
1468  printMessage(aLine);
1469  }
1470 
1471  printMessage("");
1472  }
1473 }
1474 
1476 {
1478 
1479  set_Halting(false);
1480  set_Progress(0);
1481  set_ProgressLimit(chunks.volume());
1482 
1483  for (int z=0; z<chunks.z(); z++) {
1484  for (int y=0; y<chunks.y(); y++) {
1485  QString aLine;
1486 
1487  for (int x=0; x<chunks.x(); x++) {
1488  if (get_Halting()) {
1489  break;
1490  } else {
1491  CctwIntVector3D idx(x,y,z);
1492 
1493  CctwDataChunk *chunk = m_OutputData->chunk(idx);
1494 
1495  if (chunk) {
1496  int nDeps = chunk->dependencyCount();
1497 
1498  if (nDeps > 9) {
1499  aLine += "*";
1500  } else if (nDeps >= 1) {
1501  aLine += tr("%1").arg(nDeps);
1502  } else {
1503  aLine += "0";
1504  }
1505  } else {
1506  aLine += "0";
1507  }
1508  }
1509  }
1510 
1511  printMessage(aLine);
1512  }
1513 
1514  printMessage("");
1515  }
1516 }
1517 
1519 {
1520  return m_Parameters;
1521 }
1522 
1524 {
1525  m_WorkOutstanding.fetchAndAddOrdered(amt);
1526 }
1527 
1529 {
1530  m_WorkOutstanding.fetchAndAddOrdered(-amt);
1531 }
1532 
1534 {
1535  while (m_WorkOutstanding.fetchAndAddOrdered(0) > 0) {
1536  CctwThread::msleep(100);
1537  processEvents(QEventLoop::ExcludeUserInputEvents);
1538  }
1539 }
1540 
1542 {
1543  return m_WorkOutstanding.fetchAndAddOrdered(0);
1544 }
1545 
1546 QcepIntList CctwApplication::dependencies(int chunkIdx)
1547 {
1548  return m_Transformer->dependencies(chunkIdx);
1549 }
1550 
1551 QList<CctwIntVector3D> CctwApplication::dependencies(int cx, int cy, int cz)
1552 {
1553  return m_Transformer->dependencies(cx, cy, cz);
1554 }
1555 
1557 {
1558  set_SpecDataFilePath(path);
1559 
1561 }
1562 
1564 {
1565  set_SpecDataFilePath(path);
1566 
1568 }
1569 
1570 #ifndef NO_GUI
1571 void CctwApplication::plotCurves(QwtPlotCurve *c1, QwtPlotCurve *c2, QwtPlotCurve *c3, QwtPlotCurve *c4)
1572 {
1573  if (m_Window) {
1574  m_Window->plotCurves(c1, c2, c3, c4);
1575  }
1576 }
1577 #endif
1578 
1580 {
1581  return m_InputData->chunkCount().volume();
1582 }
1583 
1585 {
1586  return m_OutputData->chunkCount().volume();
1587 }
1588 
1590 {
1591  CctwDoubleVector3D dv1(1.2,2.2,3.2), dv2(-1.2,-2.2,-3.2);
1592 
1593  CctwIntVector3D iv1(dv1), iv2(dv2);
1594 
1595  printMessage(tr("iv1 = %1, iv2 = %2").arg(iv1.toString()).arg(iv2.toString()));
1596 }
1597 
1599 {
1600  int v = data.toInt();
1601 
1602  if (m_Transformer) {
1603  printMessage(tr("Set normalization to %1").arg(v));
1604 
1605  m_Transformer->set_Normalization(v);
1606  m_OutputData->set_Normalization(v);
1607  }
1608 }
1609 
1611 {
1612  int v = data.toInt();
1613 
1614  if (m_Transformer) {
1615  printMessage(tr("Set compression to %1").arg(v));
1616 
1617  m_Transformer->set_Compression(v);
1618  m_OutputData->set_Compression(v);
1619  }
1620 }
1621 
1623 {
1624  if (m_Transformer) {
1625  m_Transformer->inputProject(m_Transformer->get_ProjectDestination(), axes);
1626  }
1627 }
1628 
1630 {
1631  if (m_Transformer) {
1632  m_Transformer->outputProject(m_Transformer->get_ProjectDestination(), axes);
1633  }
1634 }
1635 
1637 {
1638  if (m_Transformer) {
1639  m_Transformer->set_ProjectDestination(dir);
1640  }
1641 }
1642 
1644 {
1645  pushInputFile(path);
1646 }
1647 
1649 {
1650  setOutputData(path);
1651 
1652  QFuture<void> f = QtConcurrent::run(this, &CctwApplication::runMerge);
1653 
1654  while (!f.isFinished()) {
1655  CctwThread::msleep(100);
1656  processEvents(QEventLoop::ExcludeUserInputEvents);
1657  }
1658 }
1659 
1661 {
1662  m_InputData->setDataSource(get_InputFiles().at(0));
1663  m_InputData->setMaskSource(get_MaskFile());
1664  m_InputData->setAnglesSource(get_AnglesFile());
1665  m_InputData->setWeightsSource(get_WeightsFile());
1666 
1667  autoOutputFile(".nxs");
1668 
1669  m_OutputData->setDataSource(get_OutputFile());
1670 
1671  transform("");
1672 }
1673 
1675 {
1676  QVector < CctwChunkedData* > inputFiles;
1677 
1678  CctwChunkedData* outputFile = NULL;
1679 
1680  CctwIntVector3D hdfChunkSize(0,0,0);
1681  CctwIntVector3D dims(0,0,0);
1682 
1683  if (get_InputFiles().count() < 1) {
1684  printMessage("No merge inputs given");
1685  goto exit;
1686  }
1687 
1688  foreach(QString path, get_InputFiles()) {
1689  CctwChunkedData* inputFile = new CctwChunkedData(this, CctwIntVector3D(0,0,0), CctwIntVector3D(10,10,10), true, path, NULL);
1690 
1691  if (inputFile) {
1692  inputFile->setDataSource(path);
1693  if (inputFile->openInputFile()) {
1694  printMessage(tr("Opened %1 successfully").arg(path));
1695  inputFile->setChunkSize(inputFile->get_HDFChunkSize());
1696  } else {
1697  delete inputFile;
1698  printMessage(tr("Failed to open %1").arg(path));
1699  goto exit;
1700  }
1701  }
1702 
1703  inputFiles.append(inputFile);
1704  }
1705 
1706  hdfChunkSize = inputFiles[0]->get_HDFChunkSize();
1707  dims = inputFiles[0]->dimensions();
1708 
1709  foreach(CctwChunkedData* inputFile, inputFiles) {
1710  if (inputFile->get_HDFChunkSize() != hdfChunkSize) {
1711  printMessage("Input datasets do not have the same HDF chunk sizes");
1712  goto exit;
1713  }
1714 
1715  if (inputFile->dimensions() != dims) {
1716  printMessage("Input datasets do not have the same dimensions");
1717  goto exit;
1718  }
1719 
1720  inputFile->setChunkSize(hdfChunkSize);
1721  }
1722 
1723  autoOutputFile(".mrg.nxs#/entry/data");
1724  autoChunkSizes();
1725 
1726  m_OutputData->setDataSource(get_OutputFile());
1727  m_OutputData->set_HDFChunkSize(hdfChunkSize);
1728  m_OutputData->set_Compression(m_Transformer->get_Compression());
1729  m_OutputData->setDimensions(dims);
1730  m_OutputData->setChunkSize(hdfChunkSize);
1731  m_OutputData->set_Normalization(m_Transformer->get_Normalization());
1732 
1733  if (m_OutputData->openOutputFile()) {
1734  int nchunks = m_OutputData->chunkCount().volume();
1735 
1736  set_Progress(0);
1737  set_ProgressLimit(nchunks);
1738 
1739  for (int i=0; i<nchunks; i++) {
1740  set_Progress(i);
1741 
1742  foreach(CctwChunkedData* inputFile, inputFiles) {
1743  CctwDataChunk *inChunk = inputFile->readChunk(i);
1744  m_OutputData->mergeChunk(inChunk);
1745 
1746  delete inChunk;
1747  }
1748 
1750  }
1751  } else {
1752  printMessage(tr("Could not open %1 for output").arg(get_OutputFile()));
1753  goto exit;
1754  }
1755 
1756 exit:
1757 
1758  foreach(CctwChunkedData* inputFile, inputFiles) {
1759  if (inputFile) {
1760  delete inputFile;
1761  }
1762  }
1763 }
1764 
1766 {
1767  runMerge();
1768 }
1769 
1771 {
1772  m_InputData->setDataSource(get_InputFiles().at(0));
1773 
1774  if (m_Transformer) {
1775  m_Transformer->inputProject(get_OutputFile(), 7);
1776  }
1777 }
1778 
1780 {
1781  QStringList f = get_InputFiles();
1782 
1783  if (f.count() != 1) {
1784  printMessage(tr("cctw transform needs exactly 1 input file, rather than %1").arg(f.count()));
1785  } else {
1786 
1787  QFuture<void> f = QtConcurrent::run(this, &CctwApplication::runTransform);
1788 
1789  while (!f.isFinished()) {
1790  CctwThread::msleep(100);
1791  processEvents(QEventLoop::ExcludeUserInputEvents);
1792  }
1793  }
1794 }
1795 
1797 {
1798  QStringList f = get_InputFiles();
1799 
1800  if (f.count() < 1) {
1801  printMessage(tr("cctw merge needs 1 or more input files, rather than %1").arg(f.count()));
1802  } else {
1803 
1804  QFuture<void> f = QtConcurrent::run(this, &CctwApplication::runMerge);
1805 
1806  while (!f.isFinished()) {
1807  CctwThread::msleep(100);
1808  processEvents(QEventLoop::ExcludeUserInputEvents);
1809  }
1810  }
1811 }
1812 
1814 {
1815  QStringList f = get_InputFiles();
1816 
1817  if (f.count() != 1) {
1818  printMessage(tr("cctw norm needs exactly 1 input file, rather than %1").arg(f.count()));
1819  } else {
1820 
1821  QFuture<void> f = QtConcurrent::run(this, &CctwApplication::runNorm);
1822 
1823  while (!f.isFinished()) {
1824  CctwThread::msleep(100);
1825  processEvents(QEventLoop::ExcludeUserInputEvents);
1826  }
1827  }
1828 }
1829 
1831 {
1832  QStringList f = get_InputFiles();
1833 
1834  if (f.count() != 1) {
1835  printMessage(tr("cctw project needs exactly 1 input file, rather than %1").arg(f.count()));
1836  } else {
1837 
1838  QFuture<void> f = QtConcurrent::run(this, &CctwApplication::runProject);
1839 
1840  while (!f.isFinished()) {
1841  CctwThread::msleep(100);
1842  processEvents(QEventLoop::ExcludeUserInputEvents);
1843  }
1844  }
1845 }
1846 
1848 {
1849  int m = get_Mode();
1850 
1851  switch (m) {
1852  case 0:
1853  break;
1854 
1855  case TransformMode:
1856  executeTransform();
1857  break;
1858 
1859  case MergeMode:
1860  executeMerge();
1861  break;
1862 
1863  case NormMode:
1864  executeNorm();
1865  break;
1866 
1867  case ProjectMode:
1868  executeProject();
1869  break;
1870  }
1871 
1872 // printMessage(tr("Mode : %1").arg(m));
1873 
1874 // foreach (QString s, get_InputFiles()) {
1875 // printMessage(tr("File: \"%1\"").arg(s));
1876 // }
1877 }
1878 
1880 {
1881  int m = get_Mode();
1882 
1883  if (m == TransformMode) {
1884  m_InputData -> setDataSource(get_InputFiles().at(0));
1885  m_OutputData -> setDataSource(get_OutputFile());
1886  }
1887 
1888  if (m == MergeMode) {
1889  m_OutputData->set_Normalization(0);
1890  }
1891 
1892  if (m == NormMode) {
1893  m_OutputData->set_Normalization(1);
1894  }
1895 }
1896 
1898 {
1899 }
1900 
1902 {
1903  if (get_OutputFile().length() == 0) {
1904  QString commonBase = "";
1905  int first = true;
1906 
1907  foreach(QString f, get_InputFiles()) {
1908  QUrl u(f);
1909  QString fn = u.fileName();
1910  QFileInfo fi(fn);
1911  QString bn = fi.completeBaseName();
1912 
1913  if (first) {
1914  commonBase = bn;
1915  first = false;
1916  } else {
1917  QString a;
1918 
1919  for (int i=0; i<bn.length(); i++) {
1920  if (commonBase[i] == bn[i]) {
1921  a.append(bn[i]);
1922  } else break;
1923  }
1924 
1925  if (a.length() >= 1) {
1926  commonBase = a;
1927  }
1928  }
1929 
1930  printMessage(tr("Common basename %1").arg(commonBase));
1931  }
1932 
1933  QString res = commonBase + suffix;
1934 
1935  set_OutputFile(res);
1936  }
1937 }
1938 
1940 {
1941 }
CctwChunkedData * m_OutputData
void outputProject(int axes)
int dependencyCount() const
virtual QString settingsScript()
Definition: cctwobject.cpp:83
void decodeCommandLineArgs(int &argc, char *argv[])
virtual void setMaskDataset(QString desc)
void calculateChunkDependencies(int n)
void inputProject(int axes)
virtual void setWeightsSource(QString desc)
void setOmega(QString data)
void setMaskDataset(QString data)
CctwChunkedData * m_InputData
CctwIntVector3D chunkIndexFromNumber(int n)
static QString addSlashes(QString str)
void setOutputChunks(QString data)
void startupCommand(QString cmd)
void setProjectOutput(QString dir)
virtual void setAnglesSource(QString desc)
void writeChunk(int n)
static herr_t cctwH5error(hid_t h, void *data)
void saveDependencies(QString path)
CctwIntVector3D chunkSize()
CctwCrystalCoordinateParameters * m_Parameters
CctwDataChunk * chunk(int n)
void setCompression(QString data)
virtual void writeSettings(QSettings *set, QString section)
void onDebugChanged(int dbg)
QAtomicInt m_WorkOutstanding
QString toString()
void onProgress(int prg)
void executeScriptFile(QString path)
QcepSettingsSaverPtr g_Saver
void setOutputDims(QString data)
void analyzeSpecDataFile(QString path)
void setDimensions(CctwIntVector3D dim)
CctwIntVector3D dimensions
virtual void setChunks(QString desc)
void printLine(QString line)
virtual void readSettings(QSettings *set, QString section)
QcepIntList dependencies(int n)
bool openInputFile(bool quietly=false)
void analyzeSpecDataFile(QString path)
virtual void setDataset(QString desc)
CctwIntVector3D chunkCount
QcepSettingsSaverPtr m_Saver
void mergeChunk(CctwDataChunk *chunk)
CctwTransformer * m_Transformer
virtual void setDataSource(QString desc)
void setPhi(QString data)
void transform(QString desc)
virtual void setDims(QString desc)
void setOutputData(QString data)
QcepIntList dependencies(int chunkId)
T x() const
Definition: cctwvector3d.h:17
void setNormalization(QString data)
void addWorkOutstanding(int amt)
int chunkContaining(CctwIntVector3D pixelCoord)
void autoOutputFile(QString suffix)
void setChunkSize(CctwIntVector3D cksz)
void initialize(int &argc, char *argv[])
void setSubset(QString desc)
QScriptValue evaluate(QString cmd)
void addDependency(int f, int t)
void setThreads(QString desc)
CctwScriptEngine * m_ScriptEngine
QcepStringList inputFiles
CctwPEIngressCommand * m_PEIngressCommand
QAtomicInt m_LastProgress
void mergeInput(QString path)
virtual void readSettings(QSettings *set, QString section)
Definition: cctwobject.cpp:52
bool containsPixel(CctwIntVector3D pixelCoord)
void printLine(QString line)
CctwIntVector3D chunkStart()
void plotCurves(QwtPlotCurve *c1, QwtPlotCurve *c2, QwtPlotCurve *c3, QwtPlotCurve *c4)
static herr_t cctwH5print(unsigned n, const H5E_error2_t *eptr, void *data)
void analyzePEMetaData(QString path)
void setTwoTheta(QString data)
CctwComparer * m_CompareData
T z() const
Definition: cctwvector3d.h:19
void workCompleted(int amt)
void setOutputDataset(QString data)
CctwVector3D< int > CctwIntVector3D
Definition: cctwvector3d.h:70
void evaluateStartupCommand(QString cmd)
CctwqtMainWindow * m_Window
void saveDependencies(QString path)
void loadDependencies(QString path)
virtual CctwDoubleVector3D forward(CctwDoubleVector3D d)
void setChi(QString data)
void pushInputFile(QString path)
void loadDependencies(QString path)
void decodeCommandLineArgsForUnix(int &argc, char *argv[])
void printMessage(QString msg, QDateTime dt=QDateTime::currentDateTime())
void setAnglesDataset(QString data)
void installHDF5ErrorHandler()
QAtomicInt m_DependencyCounter
QcepSettingsSaverWPtr saver() const
void decodeCommandLineArgsForWindows(int &argc, char *argv[])
void setInputDataset(QString data)
virtual void writeSettings(QSettings *set, QString section)
Definition: cctwobject.cpp:39
void showHelp(QString about)
void plotCurves(QwtPlotCurve *c1, QwtPlotCurve *c2, QwtPlotCurve *c3, QwtPlotCurve *c4)
T volume() const
void mergeOutput(QString path)
void partialDependencies(QString desc)
void clearDependencies(int use)
static void msleep(unsigned long msec)
Definition: cctwthread.cpp:13
virtual void setMaskSource(QString desc)
void evaluateCommand(QString cmd)
int chunkNumberFromIndex(CctwIntVector3D chunkIdx)
void setMaskData(QString data)
void analyzePEMetaData(QString path)
virtual void setAnglesDataset(QString desc)
T y() const
Definition: cctwvector3d.h:18
void wait(QString msg)
CctwVector3D< double > CctwDoubleVector3D
Definition: cctwvector3d.h:71
void setAnglesData(QString data)
CctwApplication(int &argc, char *argv[])
CctwDataChunk * readChunk(int n)
CctwCrystalCoordinateTransform * m_Transform
CctwCrystalCoordinateParameters * parameters() const
void setInputData(QString data)
void setInputChunks(QString data)
void printMessage(QString msg, QDateTime dt=QDateTime::currentDateTime())
void reportDependencies()