1; 2; Alain C., 21 March 2013 3; 4; draft: very preliminary version for testing BYTSCL(), 5; the last case is buggy (when we have an "f_infinity", 6; max at f_infinity is convert in 255B) 7; 8; Code of BYTSCL() revised in March 2017 to take 9; into account /Nan and also to use check on Types 10; at a good level 11; 12; WARNING ! 9-March-2017 : this test is NOT working with IDL 13; when we add NAN/INF --> TEST_BYTSCL_IDL_PROBLEM 14; 15; WARNING ! in idlwave 6.1, indentation problems !! 16; ForEach/EndForEach loops indentation are not managed 17; 18; WARNING ! 15-Sept-2018 : FL don't manage as IDL & GDL: 19; Fatal if top below 0, refuse to process on Complex. 20; 21; ------------------------------------------------ 22; Modifications history : 23; 24; * AC 2017-03-13 : 25; testing the TOP keyword, no clear idea now ... 26; how to solve the differences between IDL & GDL 27; 28; * AC 2018-09-15 : after discutions & tests with Sylvain, 29; it is now clear that, in IDL, BYTSCL() does not work "well" 30; on complex input. But usually IDL enforces a simple rule : 31; applying the operation on the REAL part. Not here, eg : 32; (tested on IDL 7.0, 7.1, 8.2, 8.4, 8.5, 8.7) 33; We wrote a simple code to see it directly (pro TEST_BYTSCL_DIFF_GDL_IDL) 34; 35; ------------------------------------------------ 36; 37pro TEST_BYTSCL_DIFF_GDL_IDL 38; 39input=FINDGEN(10) 40input[5]=!values.f_nan 41input[6]=!values.f_infinity 42input=COMPLEX(input) 43; 44;print, format='(10f4.0)', input 45;print, input 46print, '1 Real Part Input : ', format='(A,10f4.0)', REAL_PART(input) 47print, '2 BYTSCL(input) : ', BYTSCL(input) 48print, '3 BYTSCL(input, /nan) : ', BYTSCL(input, /nan) 49; 50end 51; 52; in GDL : 53;1 Real Part Input : 0. 1. 2. 3. 4. NaN Inf 7. 8. 9. 54;2 BYTSCL(input) : 0 0 0 0 0 0 255 0 0 0 55;3 BYTSCL(input, /nan) : 0 28 56 85 113 0 0 199 227 255 56; 57; in IDL : 58;1 Real Part Input : 0. 1. 2. 3. 4. NaN Inf 7. 8. 9. 59;2 BYTSCL(input) : 0 0 0 0 0 0 0 0 0 0 60;3 BYTSCL(input, /nan) : 0 28 56 85 0 0 255 199 227 255 61; 62; ------------------------------------------------ 63; 64pro TEST_BYTSCL_TOP, cumul_errors, test=test, verbose=verbose 65; 66nb_errors=0 67; 68input=DIST(512) 69; 70; just testing min/max now, more to do when basics will be fixed !! 71; 72top_list=[600, 256, 255, 128, 0, -128] 73expect_max=[255, 255, 255, 128, 0, 255] 74expect_min=0 ; always 75; 76for ii=0, N_ELEMENTS(top_list)-1 do begin 77 calculus=BYTSCL(input, top=top_list[ii]) 78 result=[MIN(calculus), MAX(calculus)] 79 expected=[expect_min,expect_max[ii]] 80 ;; 81 if ARRAY_EQUAL(expected, result) NE 1 then begin 82 mess=', min/max : '+STRING(FIX(result[0]))+', '+STRING(FIX(result[1])) 83 ERRORS_ADD, nb_errors, 'Pb with top= '+STRING(top_list[ii])+mess 84 endif 85endfor 86; 87; ----- final ---- 88; 89BANNER_FOR_TESTSUITE, 'TEST_BYTSCL_RAMPS', nb_errors, /status 90ERRORS_CUMUL, cumul_errors, nb_errors 91if KEYWORD_SET(test) then STOP 92; 93end 94; 95; ------------------------------------------------ 96; basic tests on TYPE & value, without Nan or Inf 97; 98pro TEST_BYTSCL_RAMPS, cumul_errors, test=test, verbose=verbose 99; 100nb_errors=0 101; 102expected=BYTARR(10) 103expected[*]=[0,28,56,85,113,142,170,199,227,255] 104; 105for itype=1, 15 do begin 106 if (itype NE 8) then begin 107 if ISA(MAKE_ARRAY(1, type=itype),/number) then begin 108 ramp=INDGEN(10, type=itype) 109 resu=BYTSCL(ramp) 110 if ARRAY_EQUAL(expected, resu) NE 1 then begin 111 ERRORS_ADD, nb_errors, 'TYPE : '+STRING(itype) 112 endif 113 endif 114 endif 115endfor 116; 117; ----- final ---- 118; 119BANNER_FOR_TESTSUITE, 'TEST_BYTSCL_RAMPS', nb_errors, /status 120ERRORS_CUMUL, cumul_errors, nb_errors 121if KEYWORD_SET(test) then STOP 122; 123end 124; 125; ------------------------------------------------ 126; 127pro TEST_BYTSCL_RAMPS_NAN, cumul_errors, test=test, verbose=verbose 128; 129nb_errors=0 130; 131expected=BYTARR(10) 132expected[*]=[0,28,56,85,113,142,170,199,227,255] 133; 134expected_nan=BYTARR(10) 135expected_nan[6]=255 136; 137expected_nan_flag=expected 138expected_nan_flag[5:6]=0 139; 140; loop over Float/Double & Complex/Dcomplex 141; 142no_int=[4,5,6,9] 143FOREACH itype, no_int do begin 144 ;; init 145 ramp_nan_inf=INDGEN(10, type=itype) 146 ;; add Nan & Inf 147 ramp_nan_inf[5]=!values.f_nan 148 ramp_nan_inf[6]=!values.f_infinity 149 ;; 150 ;; without /nan flag 151 resu_nan=BYTSCL(ramp_nan_inf) 152 if ARRAY_EQUAL(expected_nan, resu_nan) NE 1 then begin 153 ERRORS_ADD, nb_errors, 'pb in TYPE : '+STRING(itype) 154 endif 155 ;; 156 ;; with /nan flag 157 resu_nan_flag=BYTSCL(ramp_nan_inf,/nan) 158 if ARRAY_EQUAL(expected_nan_flag, resu_nan_flag) NE 1 then begin 159 ERRORS_ADD, nb_errors, 'pb in TYPE + /NAN flag: '+STRING(itype) 160 endif 161ENDFOREACH 162; 163; ----- final ---- 164; 165BANNER_FOR_TESTSUITE, 'TEST_BYTSCL_RAMPS_NAN', nb_errors, /status 166ERRORS_CUMUL, cumul_errors, nb_errors 167if KEYWORD_SET(test) then STOP 168; 169end 170; 171; ------------------------------------------------ 172; convenience procedure used below 173pro TEST_BYTSCL_PRINT, input, expected, outpout 174print, 'Real Part Input : ', REAL_PART(input) 175print, 'Imag Part Input : ', IMAGINARY(input) 176print, 'expected : ', expected 177print, 'result : ', outpout 178end 179; 180; We have specific problems with IDL, I do not understand why 181; they cannot manage the Complex/DComplex cases, and nothing 182; in the IDL documentation in BYTSCL. Furthermore we cannot 183; simply that much the code to avoid triggering Math exceptions ... 184; 185pro TEST_BYTSCL_IDL_PROBLEM, cumul_errors, test=test, verbose=verbose, debug=debug 186; 187if KEYWORD_SET(debug) then debug=1 else debug=0 188; 189nb_errors=0 190; 191input_nan=[0., !values.f_nan, 0, 10, 20] 192input_inf=[0., !values.f_infinity, 0, 10, 20] 193input_mix=[0., !values.f_nan, 0, !values.f_infinity, 0, 10, 20] 194; 195exp_nan= BYTE([0, 0, 0, 127, 255]) 196exp_nan_flag=exp_nan 197; 198exp_inf= BYTE([0, 255, 0, 0,0 ]) 199exp_inf_flag= BYTE([0, 0, 0, 127, 255]) 200; 201exp_mix= BYTE([0, 0, 0, 255, 0, 0, 0]) 202exp_mix_flag= BYTE([0, 0, 0, 0, 0, 127, 255]) 203; 204no_int=[4,5,610,910,611,911] ;,601,901] 205FOREACH itype, no_int do begin 206 ;; 207 if itype EQ 4 then begin 208 used_nan=input_nan 209 used_inf=input_inf 210 used_mix=input_mix 211 endif 212 if itype EQ 5 then begin 213 used_nan=DOUBLE(input_nan) 214 used_inf=DOUBLE(input_inf) 215 used_mix=DOUBLE(input_mix) 216 endif 217 if itype EQ 610 OR itype EQ 910 then begin 218 if itype EQ 610 then double=0 else double=1 219 used_nan=COMPLEX(input_nan, REPLICATE(0., N_ELEMENTS(input_nan)), double=double) 220 used_inf=COMPLEX(input_inf, REPLICATE(0., N_ELEMENTS(input_inf)), double=double) 221 used_mix=COMPLEX(input_mix, REPLICATE(0., N_ELEMENTS(input_mix)), double=double) 222 endif 223 if itype EQ 611 OR itype EQ 911 then begin 224 if itype EQ 611 then double=0 else double=1 225 used_nan=COMPLEX(input_nan, input_nan, double=double) 226 used_inf=COMPLEX(input_inf, input_inf, double=double) 227 used_mix=COMPLEX(input_mix, input_mix, double=double) 228 endif 229 ;; 230 if ARRAY_EQUAL(BYTSCL(used_nan), exp_nan) NE 1 then begin 231 ERRORS_ADD, nb_errors, 'pb in TYPE + NAN + no flag: '+STRING(itype) 232 if debug then TEST_BYTSCL_PRINT, used_nan, exp_nan, BYTSCL(used_nan) 233 endif 234 if ARRAY_EQUAL(BYTSCL(used_inf), exp_inf) NE 1 then begin 235 ERRORS_ADD, nb_errors, 'pb in TYPE + Inf + no flag: '+STRING(itype) 236 if debug then TEST_BYTSCL_PRINT, used_inf, exp_inf, BYTSCL(used_inf) 237 endif 238 if ARRAY_EQUAL(BYTSCL(used_mix), exp_mix) NE 1 then begin 239 ERRORS_ADD, nb_errors, 'pb in TYPE + MIX + no flag: '+STRING(itype) 240 if debug then TEST_BYTSCL_PRINT, used_mix, exp_mix, BYTSCL(used_mix) 241 endif 242 ;; 243 ;; with the /NAN flag on 244 ;; 245 if ARRAY_EQUAL(BYTSCL(used_nan, /NAN), exp_nan_flag) NE 1 then begin 246 ERRORS_ADD, nb_errors, 'pb in TYPE + NAN + /NAN flag ON: '+STRING(itype) 247 if debug then TEST_BYTSCL_PRINT, used_nan, exp_nan_flag, BYTSCL(used_nan,/nan) 248 endif 249 if ARRAY_EQUAL(BYTSCL(used_inf, /NAN), exp_inf_flag) NE 1 then begin 250 ERRORS_ADD, nb_errors, 'pb in TYPE + Inf + /NAN flag ON: '+STRING(itype) 251 if debug then TEST_BYTSCL_PRINT, used_inf, exp_inf_flag, BYTSCL(used_inf,/nan) 252 endif 253 if ARRAY_EQUAL(BYTSCL(used_mix, /NAN), exp_mix_flag) NE 1 then begin 254 ERRORS_ADD, nb_errors, 'pb in TYPE + MIX + /NAN flag ON: '+STRING(itype) 255 if debug then TEST_BYTSCL_PRINT, used_mix, exp_mix_flag, BYTSCL(used_mix,/nan) 256 endif 257ENDFOREACH 258; 259; ----- final ---- 260; 261BANNER_FOR_TESTSUITE, 'TEST_BYTSCL_IDL_PROBLEM', nb_errors, /status 262ERRORS_CUMUL, cumul_errors, nb_errors 263if KEYWORD_SET(test) then STOP 264; 265end 266; 267; ------------------------------------------------ 268; 269pro TEST_BYTSCL, help=help, verbose=verbose, no_exit=no_exit, test=test 270; 271if KEYWORD_SET(help) then begin 272 print, 'pro TEST_BYTSCL, help=help, verbose=verbose, $' 273 print, ' no_exit=no_exit, test=test' 274 return 275endif 276; 277nl=STRING(10B) 278print, nl+"PLEASE contribute to add tests on MIN, MAX, TOP keywords"+nl 279; 280TEST_BYTSCL_TOP, nb_errors, test=test 281; 282TEST_BYTSCL_RAMPS, nb_errors, test=test 283; 284TEST_BYTSCL_RAMPS_NAN, nb_errors, test=test 285; 286; This test is a clone of previous test, testing what is "expected" 287; for types Float, Double, Complex and DComplex with NaN and Inf ... 288; In IDL, the outputs for Complex and DComplex are not understanded. 289; 290; IDL don't pass this test for COMPLEX & DCOMPLEX 291; FL don't pass this test for COMPLEX & DCOMPLEX + top below zero 292; 293TEST_BYTSCL_IDL_PROBLEM, nb_errors, test=test, verbose=verbose 294; 295; ----------------- final message ---------- 296; 297BANNER_FOR_TESTSUITE, 'TEST_BYTSCL', nb_errors 298; 299if (nb_errors GT 0) AND ~KEYWORD_SET(no_exit) then EXIT, status=1 300; 301if KEYWORD_SET(test) then STOP 302; 303end 304