Vous avez reçu un message "Your GitLab account has been locked ..." ? Pas d'inquiétude : lisez cet article https://docs.gricad-pages.univ-grenoble-alpes.fr/help/unlock/

optionsParser.py 80.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
"""
Library of SPAM functions for parsing inputs to the scripts
Copyright (C) 2020 SPAM Contributors

This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
more details.

You should have received a copy of the GNU General Public License along with
this program.  If not, see <http://www.gnu.org/licenses/>.
"""

import argparse
20
21
22
import numpy
import os

23
# Nice str2bool suggestion from Maxim (https://stackoverflow.com/questions/15008758/parsing-boolean-values-with-argparse)
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
24

25
def str2bool(v):
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
26
27
28
29
30
31
32
    if v.lower() in ('yes', 'true', 't', 'y', '1'):
        return True
    elif v.lower() in ('no', 'false', 'f', 'n', '0'):
        return False
    else:
        raise argparse.ArgumentTypeError('Boolean value expected.')

Edward Andò's avatar
Edward Andò committed
33
34
35
GLPv3descriptionHeader = "Copyright (C) 2020 SPAM developers\n"+\
                         "This program comes with ABSOLUTELY NO WARRANTY.\n"+\
                         "This is free software, and you are welcome to redistribute it under certain conditions\n\n\n"
36

37
def ldicParser(parser):
Edward Andò's avatar
Edward Andò committed
38
39
40
    parser.add_argument('-nompi',
                        action="store_false",
                        dest='MPI',
Edward Andò's avatar
Edward Andò committed
41
                        help='Force disactivate MPI? Only unse this if you cannot import mpi4py')
42

43
44
45
    parser.add_argument('inFiles',
                        nargs='+',
                        type=argparse.FileType('r'),
46
                        help="A space-separated list of two 3D greyscale tiff files to correlate, in order")
47

48
49
50
    parser.add_argument('-mf1',
                        '--maskFile1',
                        dest='MASK1',
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
51
                        default=None,
52
                        type=argparse.FileType('r'),
53
                        help="Path to tiff file containing the mask of image 1 -- masks zones not to correlate, which should be == 0")
54

Emmanuel Roubin's avatar
Emmanuel Roubin committed
55
56
57
58
59
60
    # parser.add_argument('-mf2',
    #                     '--maskFile2',
    #                     dest='MASK2',
    #                     default=None,
    #                     type=argparse.FileType('r'),
    #                     help="Path to tiff file containing the mask of image 2 -- masks correlation windows")
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
61

Edward Andò's avatar
Edward Andò committed
62
63
64
    parser.add_argument('-pf',
                        '-phiFile',
                        dest='PHIFILE',
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
65
                        default=None,
66
67
68
                        type=argparse.FileType('r'),
                        help="Path to TSV file containing initial F guess, can be single-point registration or multiple point correlation. Default = None")

Edward Andò's avatar
Edward Andò committed
69
70
    parser.add_argument('-pfb',
                        '--phiFile-bin-ratio',
71
72
                        type=int,
                        default=1,
Edward Andò's avatar
Edward Andò committed
73
                        dest='PHIFILE_BIN_RATIO',
74
                        help="Ratio of binning level between loaded Phi file and current calculation. If the input Phi file has been obtained on a 500x500x500 image and now the calculation is on 1000x1000x1000, this should be 2. Default = 1")
75
76
77
78

    parser.add_argument('-glt',
                        '--grey-low-threshold',
                        type=float,
79
                        default=-numpy.inf,
80
                        dest='GREY_LOW_THRESH',
81
82
83
84
85
86
87
88
                        help="Grey threshold on mean of reference imagette BELOW which the correlation is not performed. Default = -infinity")

    parser.add_argument('-ght',
                        '--grey-high-threshold',
                        type=float,
                        default=numpy.inf,
                        dest='GREY_HIGH_THRESH',
                        help="Grey threshold on mean of reference imagette ABOVE which the correlation is not performed. Default = infinity")
89
90
91
92
93
94
95

    parser.add_argument('-reg',
                        '--registration',
                        action="store_true",
                        dest='REG',
                        help='Perform an initial registration? Default = False')

96
97
98
99
100
101
102
    parser.add_argument('-regb',
                        '--registration-binning',
                        type=int,
                        default=1,
                        dest='REG_BIN',
                        help='Binning to apply to input images for registration. Default = 1')

103
104
105
106
107
108
109
    parser.add_argument('-regm',
                        '--registration-margin',
                        type=float,
                        default=0.1,
                        dest='REG_MARGIN',
                        help='Registration margin in proportions of image size. Default = 0.1, which means 0.1 * image size from both sides')

110
111
112
113
114
115
    parser.add_argument('-regs',
                        '--subtract-registration',
                        action="store_true",
                        dest='REGSUB',
                        help='Subtract rigid part of initial registration from output displacements? Default = False')

116
117
118
119
120
121
    parser.add_argument('-regu',
                        '--registration-update',
                        action="store_true",
                        dest='REG_UPDATE',
                        help='Update gradient in initial registration? More computation time but more robust and possibly fewer iterations. Default = False')

122
123
124
125
    parser.add_argument('-ps',
                        '--pixel-search',
                        type=str,
                        default='auto',
126
                        dest='PS',
127
                        help="Pixel search option.Accepted values are:\n\t\"auto\": disactivate pixel search if registration works, or Ffile is given." +
Edward Andò's avatar
Edward Andò committed
128
                             "\n\t\"on\": Force a pixel search in any case (rounds initial guess and can lose initial F).\n\t\"off\": block pixel search. \"auto\" is default")
129
130
131
132
133

    parser.add_argument('-psr',
                        '--pixel-search-range',
                        nargs=6,
                        type=int,
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
134
                        default=[-3, 3, -3, 3, -3, 3],
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
                        dest='PSR',
                        help='Z- Z+ Y- Y+ X- X+ ranges (in pixels) for the pxiel search. Requires pixel search to be activated. Default = +-3px')

    parser.add_argument('-psf',
                        '--pixel-search-filter',
                        type=int,
                        default=0,
                        dest='PS_FILTER',
                        help='Median filter pixel search results. Default = 0')

    # Default: node spacing equal in all three directions
    parser.add_argument('-ns',
                        '--node-spacing',
                        nargs=1,
                        type=int,
                        default=None,
                        dest='NS',
                        help="Node spacing in pixels (assumed equal in all 3 directions -- see -ns3 for different setting). Default = 10px")

    # Possible: node spacing different in all three directions
    parser.add_argument('-ns3',
                        '--node-spacing-3',
                        nargs=3,
                        type=int,
                        default=None,
                        dest='NS',
                        help="Node spacing in pixels (different in 3 directions). Default = 10, 10, 10px")

    # Default: window size equal in all three directions
    parser.add_argument('-hws',
                        '--half-window-size',
                        nargs=1,
                        type=numpy.uint,
                        default=None,
                        dest='HWS',
                        help="Half correlation window size, measured each side of the node pixel (assumed equal in all 3 directions -- see -hws3 for different setting). Default = 10px")

    # Possible: node spacing different in all three directions
    parser.add_argument('-hws3',
                        '--half-window-size-3',
                        nargs=3,
                        type=int,
                        default=None,
                        dest='HWS',
                        help="Half correlation window size, measured each side of the node pixel (different in 3 directions). Default = 10, 10, 10px")

181
182
    parser.add_argument('-nogp',
                        '--no-grid-point',
183
                        action="store_false",
184
185
                        dest='GRID_POINT',
                        help='Disactivates grid-point registration')
186

187
188
    parser.add_argument('-gpm',
                        '--grid-point-margin',
189
                        nargs=1,
190
                        type=numpy.uint,
191
                        default=[3],
192
193
                        dest='GRID_POINT_MARGIN',
                        help="Margin in pixels for grid-point registration. Default = 3px")
194

195
196
    parser.add_argument('-gpm3',
                        '--grid-point-margin3',
197
198
199
                        nargs=3,
                        type=numpy.uint,
                        default=None,
200
201
                        dest='GRID_POINT_MARGIN',
                        help="Subpixel margin for grid-point registration. Default = 3px")
202

203
204
    parser.add_argument('-gpi',
                        '--grid-point-max-iterations',
205
                        type=numpy.uint,
206
                        default=50,
207
208
                        dest='GRID_POINT_MAX_ITERATIONS',
                        help="Maximum iterations for grid-point registration. Default = 50")
209

210
211
    parser.add_argument('-gpp',
                        '--grid-point-min-phi-change',
212
213
                        type=numpy.float,
                        default=0.001,
214
215
                        dest='GRID_POINT_MIN_PHI_CHANGE',
                        help="Minimum change in Phi to consider grid-point registration as converged. Default = 0.001")
216

217
218
    parser.add_argument('-gpo',
                        '--grid-point-interpolation-order',
219
220
                        type=numpy.uint,
                        default=1,
221
222
                        dest='GRID_POINT_INTERPOLATION_ORDER',
                        help="Interpolation order for grid-point registration. Default = 1")
223

224
225
226
    parser.add_argument('-sef',
                        '--series-Ffile',
                        action="store_true",
Edward Andò's avatar
Edward Andò committed
227
                        dest='SERIES_PHIFILE',
228
229
                        help='During a total analysis, activate use of previous Ffield for next correlation')

230
231
232
233
234
235
    parser.add_argument('-sei',
                        '--series-incremental',
                        action="store_true",
                        dest='SERIES_INCREMENTAL',
                        help='Perform incremental correlations between images')

236
237
238
    parser.add_argument('-cif',
                        '--correct-input-field',
                        action="store_true",
239
240
                        dest='CORRECT_FIELD',
                        help='Activates correction of the input F field')
241

242
243
    parser.add_argument('-cni',
                        '--correct-neighbours-for-field-interpolation',
Olga Stamati's avatar
Olga Stamati committed
244
                        type=numpy.uint,
245
                        default=12,
246
                        dest='CORRECT_NEIGHBOURS',
247
                        help="Number of neighbours for field interpolation. Default = 12")
248

249
250
251
252
253
254
255
256
257
258
259
260
261
    parser.add_argument('-cmf',
                        '--correct-median-filter',
                        action="store_true",
                        dest='CORRECT_MEDIAN_FILTER',
                        help="Activates an overall median filter on the input F field")

    parser.add_argument('-cmfr',
                        '--correct-median-filter-radius',
                        type=numpy.uint,
                        default=2,
                        dest='CORRECT_MEDIAN_FILTER_RADIUS',
                        help="Radius of median filter for correction of input F field. Default = 2")

262
263
    parser.add_argument('-cdp',
                        '--correct-delta-phi-norm',
264
265
                        type=numpy.float,
                        default=0.001,
266
                        dest='CORRECT_DELTA_PHI_NORM',
267
268
                        help="Delta F norm for a return status = 1 correlation window to consider the point good. Default = 0.001")

269
270
271
272
273
274
275
    parser.add_argument('-cpscc',
                        '--correct-pixel-search-cc',
                        type=numpy.float,
                        default=0.98,
                        dest='CORRECT_PIXEL_SEARCH_CC',
                        help="Pixel search correlation coefficient to consider the point good. Default = 0.98")

276
277
278
279
280
281
282
283
284
285
286
287
    parser.add_argument('-od',
                        '--out-dir',
                        type=str,
                        default=None,
                        dest='OUT_DIR',
                        help="Output directory, default is the dirname of input file")

    parser.add_argument('-pre',
                        '--prefix',
                        type=str,
                        default=None,
                        dest='PREFIX',
Edward Andò's avatar
Edward Andò committed
288
                        help="Prefix for output files (without extension). Default is basename of input file")
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306

    parser.add_argument('-vtk',
                        '--VTKout',
                        action="store_true",
                        dest='VTK',
                        help='Activate VTK output format. Default = False')

    parser.add_argument('-tsv',
                        '--TSVout',
                        action="store_true",
                        dest='TSV',
                        help='Activate TSV output format. Default = False')

    parser.add_argument('-tif',
                        '-tiff',
                        '--TIFFout',
                        '--TIFout',
                        action="store_true",
Edward Andò's avatar
Edward Andò committed
307
308
                        dest='TIFF',
                        help='Activate TIFFoutput format. Default = False')
309
310
311

    args = parser.parse_args()

Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
312
    # 2018-03-24 check for 2D without loading images
Emmanuel Roubin's avatar
Emmanuel Roubin committed
313
    # try:
314
    # except BaseException:
315
    #     print("DICregularGrid: Input TIFPhi files need to be writeable in order to guess their dimensionality")
Emmanuel Roubin's avatar
Emmanuel Roubin committed
316
    #     exit()
Edward Andò's avatar
Edward Andò committed
317
318
319
    # 2019-03-21 EA: better check for dimensions, doesn't depend on writability of files
    import tifffile
    tiff = tifffile.TiffFile(args.inFiles[0].name)
Edward Andò's avatar
Edward Andò committed
320
    imagejSingleSlice = True
Emmanuel Roubin's avatar
Emmanuel Roubin committed
321
322
323
324
    # if tiff.imagej_metadata is not None:
    #     if 'slices' in tiff.imagej_metadata:
    #         if tiff.imagej_metadata['slices'] > 1:
    #             imagejSingleSlice = False
Edward Andò's avatar
Edward Andò committed
325

326
327
    # 2019-04-05 EA: 2D image detection approved by Christophe Golke, update for shape 2019-08-29
    if len(tiff.pages) == 1 and len(tiff.series[0].shape) == 2:
Edward Andò's avatar
Edward Andò committed
328
329
330
331
        twoD = True
    else:
        twoD = False
    tiff.close()
332

333
    # If we have no out dir specified, deliver on our default promise -- this can't be done inline before since parser.parse_args() has not been run at that stage.
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
334
335
    if args.OUT_DIR is None:
        args.OUT_DIR = os.path.dirname(args.inFiles[0].name)
336
        # However if we have no dir, notice this and make it the current directory.
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
337
338
        if args.OUT_DIR == "":
            args.OUT_DIR = "./"
339
340
341
342
343
344
    else:
        # Check existence of output directory
        try:
            if args.OUT_DIR:
                os.makedirs(args.OUT_DIR)
            else:
Emmanuel Roubin's avatar
gdic  
Emmanuel Roubin committed
345
                args.DIR_out = os.path.dirname(args.inFiles[0].name)
346
347
348
349
350
        except OSError:
            if not os.path.isdir(args.OUT_DIR):
                raise

    # Output file name prefix
351
    # 2018-11-15 EA: Setting this in the client in order not to overwrite files in a series
Emmanuel Roubin's avatar
Emmanuel Roubin committed
352
353
    # if args.PREFIX is None:
    #     args.PREFIX = os.path.splitext(os.path.basename(args.inFiles[0].name))[0]
354

355
356
357
358
    if args.PS != 'auto' and args.PS != 'on' and args.PS != 'off':
        print("\nInvalid option {} for pixel search. Setting \"auto\"".format(args.PS))
        args.PS = 'auto'

359
360
    # Catch interdependent node spacing and correlation window sizes
    if args.NS is None:
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
361
        print("\nUsing default node spacing: "),
362
        if args.HWS is None:
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
363
            print("2x default half window size"),
364
            args.HWS = [10]
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
365
366
            print("({}) which is".format(args.HWS[0])),
            args.NS = [args.HWS[0] * 2]
367
        else:
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
368
369
370
371
372
373
374
375
            print("2x user-set half window size"),
            if len(args.HWS) == 1:
                print("({}) which is".format(args.HWS[0])),
                args.NS = [int(args.HWS[0] * 2)]
            elif len(args.HWS) == 3:
                print("({} -- selecting smallest) which is".format(args.HWS)),
                args.NS = [int(min(args.HWS) * 2)]
        print(args.NS)
376
377

    # Catch 3D options
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
378
379
380
381
    if len(args.NS) == 1:
        args.NS = [args.NS[0], args.NS[0], args.NS[0]]
    if len(args.HWS) == 1:
        args.HWS = [args.HWS[0], args.HWS[0], args.HWS[0]]
382
383
    if len(args.GRID_POINT_MARGIN) == 1:
        args.GRID_POINT_MARGIN = [args.GRID_POINT_MARGIN[0], args.GRID_POINT_MARGIN[0], args.GRID_POINT_MARGIN[0]]
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
384

385
386
    if type(args.GRID_POINT_MAX_ITERATIONS) == list:
        args.GRID_POINT_MAX_ITERATIONS = args.GRID_POINT_MAX_ITERATIONS[0]
387

388
389
    # Catch and overwrite 2D options
    if twoD:
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
390
        args.NS[0] = 1
391
        args.HWS[0] = 0
392
        args.GRID_POINT_MARGIN[0] = 0
393
394
        args.PSR[0] = 0
        args.PSR[1] = 0
395

396
397
398
399
400
401
402
403
404
    # Behaviour undefined for series run and im1 mask since im1 will change, complain and continue
    if args.MASK1 is not None and args.SERIES_INCREMENTAL:
        print("#############################################################")
        print("#############################################################")
        print("###  WARNING: You set an im1 mask and an incremental      ###")
        print("###  series correlation, meaning that im1 will change...  ###")
        print("#############################################################")
        print("#############################################################")

405
    # Make sure at least one output format has been asked for
Edward Andò's avatar
Edward Andò committed
406
    if args.VTK + args.TSV + args.TIFF== 0:
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
407
408
        print("#############################################################")
        print("#############################################################")
Edward Andò's avatar
Edward Andò committed
409
        print("###  WARNING: No output type of VTK, TSV and TIFFoptions  ###")
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
410
411
412
        print("###  Are you sure this is right?!                         ###")
        print("#############################################################")
        print("#############################################################")
413
414

    if args.REG_MARGIN > 0.45:
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
415
        print("Registration margin cannot be bigger than 0.45 since 0.5 would contain no data!!")
416

Edward Andò's avatar
Edward Andò committed
417
    if args.SERIES_PHIFILE:
418
419
420
        args.TSV = True

    # just keep the name for this one
Edward Andò's avatar
Edward Andò committed
421
422
    if args.PHIFILE is not None:
        args.PHIFILE = args.PHIFILE.name
423

424
425
426
    return args


427
def ddicParser(parser):
428
429
430
431
432
    parser.add_argument('im1',
                        metavar='im1',
                        type=argparse.FileType('r'),
                        help="Greyscale image of reference state for correlation")

433
434
435
436
437
    parser.add_argument('lab1',
                        metavar='lab1',
                        type=argparse.FileType('r'),
                        help="Labelled image of reference state for correlation")

438
439
440
441
    parser.add_argument('im2',
                        metavar='im2',
                        type=argparse.FileType('r'),
                        help="Greyscale image of deformed state for correlation")
442
443
444
445
446
447

    parser.add_argument('-ps',
                        '--pixel-search',
                        type=str,
                        default='auto',
                        dest='PS',
448
                        help="Pixel search option.Accepted values are:\n\t\"auto\": disactivate pixel search if registration works, or Ffile is given." +
Edward Andò's avatar
Edward Andò committed
449
                             "\n\t\"on\": Force a pixel search in any case (rounds initial guess and can lose initial F).\n\t\"off\": block pixel search. \"auto\" is default")
Emmanuel Roubin's avatar
Emmanuel Roubin committed
450

451
452
453
454
    parser.add_argument('-nompi',
                        action="store_false",
                        dest='MPI',
                        help='Disactivate MPI parallelisation?')
455
456
457
458
459

    parser.add_argument('-psr',
                        '--pixel-search-range',
                        nargs=6,
                        type=int,
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
460
                        default=[-3, 3, -3, 3, -3, 3],
461
462
463
                        dest='PSR',
                        help='Z- Z+ Y- Y+ X- X+ ranges (in pixels) for the pxiel search. Requires pixel search to be activated. Default = +-3px')

464
465
    parser.add_argument('-nolc',
                        '--no-label-correlation',
466
                        action="store_false",
467
468
                        dest='LABEL_CORRELATE',
                        help='Disactivate label registration?')
469
470
471

    parser.add_argument('-ld',
                        '--label-dilate',
472
                        type=int,
473
474
475
476
                        default=1,
                        dest='LABEL_DILATE',
                        help="Number of times to dilate labels. Default = 1")

Edward Andò's avatar
Edward Andò committed
477
478
479
480
481
482
483
    parser.add_argument('-ldmax',
                        '--label-dilate-maximum',
                        type=int,
                        default=None,
                        dest='LABEL_DILATE_MAX',
                        help="Maximum dilation for label if they don't converge with -ld setting. Default = same as -ld setting")

484
485
486
487
488
489
490
    parser.add_argument('-vt',
                        '--volume-threshold',
                        type=numpy.uint,
                        default=100,
                        dest='VOLUME_THRESHOLD',
                        help="Volume threshold below which labels are ignored. Default = 100")

491
492
493
494
495
496
    parser.add_argument('-reg',
                        '--registration',
                        action="store_true",
                        dest='REG',
                        help='Perform an initial registration? Default = False')

497
498
    parser.add_argument('-regb',
                        '--registration-binning',
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
499
500
                        type=int,
                        default=1,
501
502
503
                        dest='REG_BIN',
                        help='Binning to apply to input images for registration. Default = 1')

504
505
506
507
508
509
510
    parser.add_argument('-regm',
                        '--registration-margin',
                        type=float,
                        default=0.1,
                        dest='REG_MARGIN',
                        help='Registration margin in proportions of image size. Default = 0.1, which means 0.1 * image size from both sides')

511
512
513
514
515
516
    parser.add_argument('-regs',
                        '--subtract-registration',
                        action="store_true",
                        dest='REGSUB',
                        help='Subtract rigid part of initial registration from output displacements? Default = False')

517
518
519
520
521
522
    parser.add_argument('-regu',
                        '--registration-update',
                        action="store_true",
                        dest='REG_UPDATE',
                        help='Update gradient in initial registration? More computation time but more robust and possibly fewer iterations. Default = False')

Edward Andò's avatar
Edward Andò committed
523
524
525
    parser.add_argument('-pf',
                        '-phiFile',
                        dest='PHIFILE',
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
526
                        default=None,
527
528
529
                        type=argparse.FileType('r'),
                        help="Path to TSV file containing initial F guess, can be single-point registration or multiple point correlation. Default = None")

Edward Andò's avatar
Edward Andò committed
530
531
    parser.add_argument('-pfb',
                        '--phiFile-bin-ratio',
532
533
                        type=int,
                        default=1,
Edward Andò's avatar
Edward Andò committed
534
                        dest='PHIFILE_BIN_RATIO',
535
                        help="Ratio of binning level between loaded Phi file and current calculation. If the input Phi file has been obtained on a 500x500x500 image and now the calculation is on 1000x1000x1000, this should be 2. Default = 1")
536

537
538
539
    parser.add_argument('-pfd',
                        '--phiFile-direct',
                        action="store_true",
540
                        #default=1,
541
                        dest='PHIFILE_DIRECT',
542
                        help="Trust the Phi file completely? This option ignores and overrides -cif and requires labels to be aligned between Phi file and labelled image. Default = False")
543

544
545
546
547
548
549
550
551
552
553
554
    parser.add_argument('-cif',
                        '--correct-input-field',
                        action="store_true",
                        dest='CF',
                        help='Correction of the input F field. Default = True')

    parser.add_argument('-nfi',
                        '--neighbours-for-field-interpolation',
                        type=numpy.uint,
                        default=12,
                        dest='NEIGHBOURS',
555
                        help="Number of neighbours for field interpolation. Default = 12")
556

557
558
559
560
561
562
    parser.add_argument('-nomask',
                        '--no-mask',
                        action="store_false",
                        dest='MASK',
                        help='Don\'t mask each label\'s image')

563
564
    parser.add_argument('-lcm',
                        '--label-correlate-margin',
565
                        type=numpy.uint,
566
567
                        default=5,
                        dest='LABEL_CORRELATE_MARGIN',
568
                        help="Margin in pixels for grid-point registration to be added to label dilate. Default = 2px")
569

570
571
    parser.add_argument('-lci',
                        '--label-correlate-max-iterations',
572
                        type=numpy.uint,
573
                        default=50,
574
                        dest='LABEL_CORRELATE_MAX_ITERATIONS',
575
                        help="Maximum iterations for grid-point registration. Default = 50")
576

577
578
    parser.add_argument('-lcp',
                        '--label-correlate-min-phi-change',
579
580
                        type=numpy.float,
                        default=0.001,
581
                        dest='LABEL_CORRELATE_MIN_PHI_CHANGE',
582
                        help="Minimum change in Phi to consider grid-point registration as converged. Default = 0.001")
583

584
585
    parser.add_argument('-lco',
                        '--label-correlate-interpolation-order',
586
                        type=numpy.uint,
587
                        default=1,
588
                        dest='LABEL_CORRELATE_INTERPOLATION_ORDER',
589
                        help="Interpolation order for grid-point registration. Default = 3")
590

Edward Andò's avatar
Edward Andò committed
591
    parser.add_argument('-lcnr',
592
593
594
595
596
597
598
599
600
                        '--label-correlate-non-rigid',
                        action="store_false",
                        dest='LABEL_CORRELATE_RIGID',
                        help='Activate non-rigid registration for each label')

    parser.add_argument('-lcug',
                        '--label-correlate-update-gradient',
                        action="store_true",
                        dest='LABEL_CORRELATE_UPDATE_GRADIENT',
601
602
603
604
605
606
607
                        help='Update gradient in label registration? More computation time but more robust and possibly fewer iterations.')

    parser.add_argument('-lcmo',
                        '--label-correlate-mask-others',
                        action="store_false",
                        dest='LABEL_CORRELATE_MASK_OTHERS',
                        help='Prevent masking other labels when dilating?')
608

609
610
611
612
613
614
615
616
617
618
619
620
    parser.add_argument('-od',
                        '--out-dir',
                        type=str,
                        default=None,
                        dest='OUT_DIR',
                        help="Output directory, default is the dirname of input file")

    parser.add_argument('-pre',
                        '--prefix',
                        type=str,
                        default=None,
                        dest='PREFIX',
Edward Andò's avatar
Edward Andò committed
621
                        help="Prefix for output files (without extension). Default is basename of input file")
622

623
624
625
626
627
    parser.add_argument('-skp',
                        '--skip',
                        action="store_true",
                        default=0,
                        dest='SKIP_PARTICLES',
628
                        help="Read the return status of the Phi file run ddic only for the non-converged grains. Default = False")
629

630
631
632
633
634
635
636
    parser.add_argument('-d',
                        '--debug',
                        action="store_true",
                        default=0,
                        dest='DEBUG',
                        help="Extremely verbose mode with graphs and text output. Only use for a few particles. Do not use with mpirun")

637
638
639
    args = parser.parse_args()

    # If we have no out dir specified, deliver on our default promise -- this can't be done inline before since parser.parse_args() has not been run at that stage.
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
640
641
    if args.OUT_DIR is None:
        args.OUT_DIR = os.path.dirname(args.lab1.name)
642
        # However if we have no dir, notice this and make it the current directory.
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
643
644
        if args.OUT_DIR == "":
            args.OUT_DIR = "./"
645
646
647
648
649
    else:
        # Check existence of output directory
        try:
            if args.OUT_DIR:
                os.makedirs(args.OUT_DIR)
650
            else:
Emmanuel Roubin's avatar
gdic  
Emmanuel Roubin committed
651
                args.DIR_out = os.path.dirname(args.lab1.name)
652
653
654
655
656
        except OSError:
            if not os.path.isdir(args.OUT_DIR):
                raise

    # Output file name prefix
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
657
    if args.PREFIX is None:
Emmanuel Roubin's avatar
Emmanuel Roubin committed
658
        args.PREFIX = os.path.splitext(os.path.basename(args.im1.name))[0] + "-" + os.path.splitext(os.path.basename(args.im2.name))[0]
659

Edward Andò's avatar
Edward Andò committed
660
661
662
663
664
665
666
667
    # Set label dilate max as label dilate if it is none
    if args.LABEL_DILATE_MAX is None:
        args.LABEL_DILATE_MAX = args.LABEL_DILATE

    if args.LABEL_DILATE_MAX < args.LABEL_DILATE:
        print("spam-ddic: Warining \"label dilate max\" is less than \"label dilate\" setting them equal")
        args.LABEL_DILATE_MAX = args.LABEL_DILATE

668
    return args
669
670


Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
671
def multiModalRegistrationParser(parser):
672
    import spam.DIC
Edward Andò's avatar
Edward Andò committed
673
    import numpy
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708

    parser.add_argument('im1',
                        metavar='im1',
                        type=argparse.FileType('r'),
                        help="Greyscale image of reference state for correlation")

    parser.add_argument('im2',
                        metavar='im2',
                        type=argparse.FileType('r'),
                        help="Greyscale image of deformed state for correlation")

    parser.add_argument('-im1min',
                        type=float,
                        default=None,
                        dest='IM1_MIN',
                        help="Minimum of im1 for greylevel scaling. Default = im1.min()")

    parser.add_argument('-im1max',
                        type=float,
                        default=None,
                        dest='IM1_MAX',
                        help="Maximum of im1 for greylevel scaling. Default = im1.max()")

    parser.add_argument('-im2min',
                        type=float,
                        default=None,
                        dest='IM2_MIN',
                        help="Minimum of im2 for greylevel scaling. Default = im2.min()")

    parser.add_argument('-im2max',
                        type=float,
                        default=None,
                        dest='IM2_MAX',
                        help="Maximum of im2 for greylevel scaling. Default = im2.max()")

Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
709
710
711
712
713
714
715
716
717
718
719
720
721
722
    parser.add_argument('-im1th',
                        '--im1-threshold',
                        type=int,
                        default=0,
                        dest='IM1_THRESHOLD',
                        help='Greylevel threshold for image 1. Below this threshold, peaks in the histogram are ignored.')

    parser.add_argument('-im2th',
                        '--im2-threshold',
                        type=int,
                        default=0,
                        dest='IM2_THRESHOLD',
                        help='Greylevel threshold for image 2. Below this threshold, peaks in the histogram are ignored.')

723
724
    parser.add_argument('-bin',
                        '--bin-levels',
Edward Andò's avatar
Edward Andò committed
725
                        type=int,
Edward Andò's avatar
Edward Andò committed
726
727
728
                        default=1,
                        dest='NBINS',
                        help='Number of binning levels to apply to the data (if given 3, the binning levels used will be 4 2 1). The -phase option is necessary and should define this many phases (i.e., 3 different numbers in this example)')
729
730
731
732
733
734
735

    parser.add_argument('-ph',
                        '--phases',
                        nargs='+',
                        type=int,
                        default=[2],
                        dest='PHASES',
736
                        help='Number of phases?')
737
738
739

    parser.add_argument('-jhb',
                        '--joint-histogram-bins',
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
740
                        # nargs=1,
741
742
743
744
745
                        type=int,
                        default=128,
                        dest='JOINT_HISTO_BINS',
                        help='The number of greylevel bins for both images in the joint histogram')

Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
746
747
748
749
750
    parser.add_argument('-dst',
                        '--dist-between-max',
                        type=int,
                        default=None,
                        dest='DIST_BETWEEN_MAX',
Emmanuel Roubin's avatar
Emmanuel Roubin committed
751
752
753
754
755
756
757
758
                        help='Minimal distance between two maxima in the histogram')

    parser.add_argument('-fdi',
                        '--fit-distance',
                        type=float,
                        default=None,
                        dest='FIT_DISTANCE',
                        help='Distance considered around a peak for the Gaussian ellipsoid fitting')
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
759

Emmanuel Roubin's avatar
Emmanuel Roubin committed
760
761
762
763
764
    parser.add_argument('-voc',
                        '--voxel-coverage',
                        type=float,
                        default=1.0,
                        dest='VOXEL_COVERAGE',
Emmanuel Roubin's avatar
Emmanuel Roubin committed
765
                        help='Percentage (between 0 and 1) of voxel coverage of the phases in the joint histogram')
Emmanuel Roubin's avatar
Emmanuel Roubin committed
766

767
768
769
770
771
772
773
774
775
776
777
778
    parser.add_argument('-int',
                        '--interactive',
                        action="store_true",
                        dest='INTERACTIVE',
                        help='Present live-updating plots to the user')

    parser.add_argument('-gra',
                        '--graphs',
                        action="store_true",
                        dest='GRAPHS',
                        help='Save graphs to file')

Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
779
780
781
782
783
784
785
    parser.add_argument('-ssl',
                        '--show-slice-axis',
                        type=int,
                        default=0,
                        dest='SHOW_SLICE_AXIS',
                        help='Axis of the cut used for the plots')

786
    parser.add_argument('-spp',
787
                        '--grid-point-min-phi-change',
788
                        type=numpy.float,
789
                        default=0.0005,
790
                        dest='GRID_POINT_MIN_PHI_CHANGE',
Edward Andò's avatar
Edward Andò committed
791
792
793
                        help="Subpixel min change in Phi to stop iterations. Default = 0.001")

    parser.add_argument('-spi',
794
                        '--grid-point-max-iterations',
Edward Andò's avatar
Edward Andò committed
795
796
                        type=numpy.uint,
                        default=50,
797
                        dest='GRID_POINT_MAX_ITERATIONS',
Edward Andò's avatar
Edward Andò committed
798
                        help="Max number of iterations to optimise Phi. Default = 50")
799

Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
800
801
802
803
804
    # parser.add_argument('-tmp',
    #                     '--writeTemporaryFiles',
    #                     action="store_true",
    #                     dest='DATA',
    #                     help='Save temporary files (joint histogram) to \"dat\" file')
805

806
807
808
809
810
    #parser.add_argument('-loadprev',
                        #'--load-previous-iteration',
                        #action="store_true",
                        #dest='LOADPREV',
                        #help='Load output pickle files from previous iterations (2* coarser binning)')
Edward Andò's avatar
Edward Andò committed
811

812
    parser.add_argument('-mar',
Emmanuel Roubin's avatar
Emmanuel Roubin committed
813
                        '--margin',
814
815
                        type=float,
                        default=0.1,
Emmanuel Roubin's avatar
Emmanuel Roubin committed
816
817
818
819
820
821
822
823
824
                        dest='MARGIN',
                        help='Margin of both images. Default = 0.1, which means 0.1 * image size from both sides')

    parser.add_argument('-cro',
                        '--crop',
                        type=float,
                        default=0.1,
                        dest='CROP',
                        help='Initial crop of both images. Default = 0.1, which means 0.1 * image size from both sides')
825

826
827
828
829
830
    #parser.add_argument('-pif',
                        #default=None,
                        #type=argparse.FileType('rb'),
                        #dest='FGUESS_PICKLE',
                        #help="Pickle file name for initial guess. Should be in position 0 in the array and labeled as 'F' as for registration.")
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
831

Edward Andò's avatar
Edward Andò committed
832
    # Remove next two arguments for F input, and replace with displacement and rotation inputs on command line
833
834
835
    parser.add_argument('-pf',
                        '--phiFile',
                        dest='PHIFILE',
836
                        default=None,
837
                        type=argparse.FileType('r'),
838
                        help="Path to TSV file containing a single Phi guess (not a field) that deforms im1 onto im2. Default = None")
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
839
840
841
842
843

    # parser.add_argument('-Ffb',
    # '--Ffile-bin-ratio',
    # type=int,
    # default=1,
Edward Andò's avatar
Edward Andò committed
844
    # dest='PHIFILE_BIN_RATIO',
845
    # help="Ratio of binning level between loaded Phi file and current calculation. If the input Phi file has been obtained on a 500x500x500 image and now the calculation is on 1000x1000x1000, this should be 2. Default = 1")
Edward Andò's avatar
Edward Andò committed
846

847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
    # parser.add_argument('-tra',
    # '--translation',
    # nargs=3,
    # type=float,
    # default=None,
    # dest='TRA',
    # help="Z, Y, X initial displacements to apply at the bin 1 scale")

    # parser.add_argument('-rot',
    # '--rotation',
    # nargs=3,
    # type=float,
    # default=None,
    # dest='ROT',
    # help="Z, Y, X components of rotation vector to apply at the bin 1 scale")
862
863
864
865
866
867
868
869
870
871
872
873
874

    parser.add_argument('-od',
                        '--out-dir',
                        type=str,
                        default=None,
                        dest='OUT_DIR',
                        help="Output directory, default is the dirname of input file")

    parser.add_argument('-pre',
                        '--prefix',
                        type=str,
                        default=None,
                        dest='PREFIX',
Edward Andò's avatar
Edward Andò committed
875
                        help="Prefix for output files (without extension). Default is basename of input file")
876
877
878
879

    args = parser.parse_args()

    # The number of bin levels must be the same as the number of phases
Edward Andò's avatar
Edward Andò committed
880
    if (args.NBINS != len(args.PHASES)):
881
882
883
        print("\toptionsParser.multiModalRegistrationParser(): Number of bin levels and number of phases not the same, exiting")
        exit()

Edward Andò's avatar
Edward Andò committed
884
885
886
    # For back compatibility, generate list of bins
    args.BINS = []
    for i in range(args.NBINS)[::-1]:
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
887
        args.BINS.append(2**i)
Edward Andò's avatar
Edward Andò committed
888

889
    # If we have no out dir specified, deliver on our default promise -- this can't be done inline before since parser.parse_args() has not been run at that stage.
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
890
891
    if args.OUT_DIR is None:
        args.OUT_DIR = os.path.dirname(args.im1.name)
892
        # However if we have no dir, notice this and make it the current directory.
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
893
894
        if args.OUT_DIR == "":
            args.OUT_DIR = "./"
895
896
897
898
899
900
    else:
        # Check existence of output directory
        try:
            if args.OUT_DIR:
                os.makedirs(args.OUT_DIR)
            else:
Emmanuel Roubin's avatar
gdic  
Emmanuel Roubin committed
901
                args.DIR_out = os.path.dirname(args.im1.name)
902
903
904
905
        except OSError:
            if not os.path.isdir(args.OUT_DIR):
                raise

Edward Andò's avatar
Edward Andò committed
906
    # Get initial guesses
907
908
    if args.PHIFILE is not None:
        import spam.helpers
909
        args.FGUESS = spam.helpers.readCorrelationTSV(args.PHIFILE.name, readConvergence=False, readOnlyDisplacements=False)['PhiField'][0]
Edward Andò's avatar
Edward Andò committed
910
911
912
    else:
        args.FGUESS = numpy.eye(4)

913
    # Output file name prefix
Emmanuel Roubin's avatar
MMR  
Emmanuel Roubin committed
914
    if args.PREFIX is None:
Emmanuel Roubin's avatar
Emmanuel Roubin committed
915
        args.PREFIX = os.path.splitext(os.path.basename(args.im1.name))[0] + "-" + os.path.splitext(os.path.basename(args.im2.name))[0]
916
917

    return args
Emmanuel Roubin's avatar
gdic  
Emmanuel Roubin committed
918
919


Emmanuel Roubin's avatar
Emmanuel Roubin committed
920
def gdicParser(parser):
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
    parser.add_argument('inFiles',
                        nargs='+',
                        type=argparse.FileType('r'),
                        help="A space-separated list of two 3D greyscale tiff files to correlate, in order")

    parser.add_argument('-mf1',
                        '--maskFile1',
                        dest='MASK1',
                        default=None,
                        type=argparse.FileType('r'),
                        help="Path to tiff file containing the mask of image 1 -- masks  zones not to correlate")

    parser.add_argument('-mf2',
                        '--maskFile2',
                        dest='MASK2',
                        default=None,
                        type=argparse.FileType('r'),
                        help="Path to tiff file containing the mask of image 2 -- masks correlation windows")

    parser.add_argument('-pf',
                        '-phiFile',
                        dest='PHIFILE',
                        default=None,
                        type=argparse.FileType('r'),
                        help="Path to TSV file containing initial F guess, can be single-point registration or multiple point correlation. Default = None")

    parser.add_argument('-pfb',
                        '--phiFile-bin-ratio',
                        type=int,
                        default=1,
                        dest='PHIFILE_BIN_RATIO',
952
                        help="Ratio of binning level between loaded Phi file and current calculation. If the input Phi file has been obtained on a 500x500x500 image and now the calculation is on 1000x1000x1000, this should be 2. Default = 1")
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967

    # parser.add_argument('-glt',
    #                     '--grey-low-threshold',
    #                     type=float,
    #                     default=-numpy.inf,
    #                     dest='GREY_LOW_THRESH',
    #                     help="Grey threshold on mean of reference imagette BELOW which the correlation is not performed. Default = -infinity")
    #
    # parser.add_argument('-ght',
    #                     '--grey-high-threshold',
    #                     type=float,
    #                     default=numpy.inf,
    #                     dest='GREY_HIGH_THRESH',
    #                     help="Grey threshold on mean of reference imagette ABOVE which the correlation is not performed. Default = infinity")

Edward's avatar
Edward committed
968
969
970
971
972
973
    parser.add_argument('-d',
                        '--debug',
                        action="store_true",
                        dest='DEBUG_FILES',
                        help='Output debug files during iterations? Default = False')

974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
    parser.add_argument('-reg',
                        '--registration',
                        action="store_true",
                        dest='REG',
                        help='Perform an initial registration? Default = False')

    parser.add_argument('-regb',
                        '--registration-binning',
                        type=int,
                        default=1,
                        dest='REG_BIN',
                        help='Binning to apply to input images for registration. Default = 1')

    parser.add_argument('-regm',
                        '--registration-margin',
                        type=float,
                        default=0.1,
                        dest='REG_MARGIN',
                        help='Registration margin in proportions of image size. Default = 0.1, which means 0.1 * image size from both sides')

994
995
996
997
998
999
    parser.add_argument('-regu',
                        '--registration-update',
                        action="store_true",
                        dest='REG_UPDATE',
                        help='Update gradient in initial registration? More computation time but more robust and possibly fewer iterations. Default = False')

1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
    parser.add_argument('-mit',
                        '--max-iterations',
                        type=numpy.uint,
                        default=25,
                        dest='MAX_ITERATIONS',
                        help="Max iterations for global correlation. Default = 25")

    parser.add_argument('-cc',
                        '--convergence-criterion',
                        type=numpy.float,
                        default=0.01,
                        dest='CONVERGENCE_CRITERION',
                        help="Displacement convergence criterion in pixels (norm of incremental displacements). Default = 0.01")

    parser.add_argument('-str',
                        '--calculate-strain',
                        action="store_true",
                        dest='STRAIN',
                        help='Calculate strain? This is added to the VTK output files')
Emmanuel Roubin's avatar
gdic  
Emmanuel Roubin committed
1019

1020
1021
1022
1023
1024
    parser.add_argument('-ss',
                        '--small--strains',
                        action="store_true",
                        dest='SMALL_STRAINS',
                        help='Strain field is computed under the hypothesis of small strain. Default = False')
Emmanuel Roubin's avatar
gdic  
Emmanuel Roubin committed
1025

1026
    # parser.add_argument('-spo',
1027
    #                     '--grid-point-interpolation-order',
1028
1029
    #                     type=numpy.uint,
    #                     default=1,
1030
    #                     dest='GRID_POINT_INTERPOLATION_ORDER',
1031
    #                     help="Subpixel interpolation order. Default = 1")
Emmanuel Roubin's avatar
gdic  
Emmanuel Roubin committed
1032

1033
1034
1035
1036
1037
    # parser.add_argument('-cif',
    #                     '--correct-input-field',
    #                     action="store_true",
    #                     dest='CF',
    #                     help='Correction of the input F field. Default = True')
Emmanuel Roubin's avatar
gdic  
Emmanuel Roubin committed
1038

1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
    # parser.add_argument('-nfi',
    #                     '--neighbours-for-field-interpolation',
    #                     type=numpy.uint,
    #                     default=12,
    #                     dest='NEIGHBOURS',
    #                     help="Neighbours for field interpolation. Default = 12")

    parser.add_argument('-od',
                        '--out-dir',
                        type=str,
                        default=None,
                        dest='OUT_DIR',
                        help="Output directory, default is the dirname of input file")

    parser.add_argument('-pre',
                        '--prefix',
                        type=str,
Emmanuel Roubin's avatar
Emmanuel Roubin committed
1056
                        default=None,
1057
                        dest='PREFIX',
Edward Andò's avatar
Edward Andò committed
1058
                        help="Prefix for output files (without extension). Default is basename of input file")
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071

    parser.add_argument('-Mfile',
                        dest='MESH_FILE',
                        default=None,
                        type=argparse.FileType('rb'),
                        help="Path to pickle file containing mesh information needed for the correlation (coordinates, connectivity, labels and padding). Default = None.")

    parser.add_argument('-Mcube',
                        '--mesh-cuboid',
                        nargs=7,
                        type=numpy.float,
                        default=None,
                        dest='MESH_CUBOID',
1072
                        help='7 floats parameters to mesh a cuboid. first 3 are position of the bottom corner (Z, Y, X), next 3 are the lenghts of the cube (Z, Y, X) and the last one is the average length between two nodes.')
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096

    args = parser.parse_args()

    if args.MESH_FILE is None and args.MESH_CUBOID is None:
        print("\tgdic: a mesh is needed. Use one of this option: -Mcube or -Mfile.")
        print("\tgdic: exiting.")
        exit()

    # If we have no out dir specified, deliver on our default promise -- this can't be done inline before since parser.parse_args() has not been run at that stage.
    if args.OUT_DIR is None:
        args.OUT_DIR = os.path.dirname(args.inFiles[0].name)
        # However if we have no dir, notice this and make it the current directory.
        if args.OUT_DIR == "":
            args.OUT_DIR = "./"
    else:
        # Check existence of output directory
        try:
            if args.OUT_DIR:
                os.makedirs(args.OUT_DIR)
            else:
                args.DIR_out = os.path.dirname(args.inFiles[0].name)
        except OSError:
            if not os.path.isdir(args.OUT_DIR):
                raise
Emmanuel Roubin's avatar
gdic  
Emmanuel Roubin committed
1097

1098
1099
    # Output file name prefix
    if args.PREFIX is None:
Emmanuel Roubin's avatar
Emmanuel Roubin committed
1100
        args.PREFIX = "GDIC_{}-{}".format(os.path.splitext(os.path.basename(args.inFiles[0].name))[0], os.path.splitext(os.path.basename(args.inFiles[1].name))[0])
Emmanuel Roubin's avatar
gdic  
Emmanuel Roubin committed
1101

1102
1103
    if type(args.MAX_ITERATIONS) == list:
        args.MAX_ITERATIONS = args.MAX_ITERATIONS[0]
Emmanuel Roubin's avatar
gdic  
Emmanuel Roubin committed
1104

1105
1106
    if args.REG_MARGIN > 0.45:
        print("Registration margin cannot be bigger than 0.45 since 0.5 would contain no data!!")
Emmanuel Roubin's avatar
gdic  
Emmanuel Roubin committed
1107

1108
    return args
1109

Edward Andò's avatar
Edward Andò committed
1110

1111
def regularStrainParser(parser):
1112
1113
1114
1115
1116
    parser.add_argument('inFile',
                        metavar='inFile',
                        type=argparse.FileType('r'),
                        help='Path to TSV file containing the result of the correlation')

1117
1118
1119
1120
1121
1122
1123
1124
    parser.add_argument('-comp',
                        '--strain-components',
                        nargs='*',
                        type=str,
                        default=['vol', 'dev'],
                        dest='COMPONENTS',
                        help='Selection of which strain components to save, options are: vol (volumetric strain), dev (deviatoric strain), volss (volumetric strain in small strains), devss (deviatoric strain in small strains), r (rotation vector), z (zoom vector), U (right-hand stretch tensor), e (strain tensor in small strains)')

1125
1126
1127
1128
1129
1130
    parser.add_argument('-mask',
                        '--mask',
                        action="store_true",
                        dest='MASK',
                        help='Mask correlation points according to return status')

1131
1132
1133
1134
1135
1136
    parser.add_argument('-r',
                        '--neighbourhood-radius-for-strain-calculation',
                        type=float,
                        default=1.5,
                        dest='STRAIN_NEIGHBOUR_RADIUS',
                        help="Radius (in units of nodeSpacing) inside which to select neighbours for displacement gradient calculation. Ignored if -cub is set. Default = 1.5")
1137
1138
1139

    parser.add_argument('-cub',
                        '--cubic-element',
1140
                        '--Q8',
1141
1142
1143
1144
                        action="store_true",
                        dest='Q8',
                        help='Use Q8 element interpolation? More noisy and strain values not centred on displacement points')

1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
    parser.add_argument('-cif',
                        '--correct-input-field',
                        action="store_true",
                        dest='CORRECT_FIELD',
                        help='Activates correction of the input displacement field')

    parser.add_argument('-cni',
                        '--correct-neighbours-for-field-interpolation',
                        type=numpy.uint,
                        default=12,
                        dest='CORRECT_NEIGHBOURS',
                        help="Neighbours for field interpolation. Default = 12")

    parser.add_argument('-cmf',
                        '--correct-median-filter',
                        action="store_true",
                        dest='CORRECT_MEDIAN_FILTER',
                        help="Activates an overall median filter on the input displacement field")

    parser.add_argument('-cmfr',
                        '--correct-median-filter-radius',
                        type=numpy.uint,
                        default=2,
                        dest='CORRECT_MEDIAN_FILTER_RADIUS',
                        help="Radius of median filter for correction of input displacement field. Default = 2")

1171
1172
    parser.add_argument('-cdp',
                        '--correct-delta-phi-norm',
1173
                        type=numpy.float,