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