1 | SBT README DCW 6/4/99 |
---|
2 | |
---|
3 | Solids Batch Test |
---|
4 | ----------------- |
---|
5 | |
---|
6 | This facility is designed to test the correct behavior of CSG solids. |
---|
7 | It features: |
---|
8 | |
---|
9 | 1. Interactive creation of solids. Solid parameters can |
---|
10 | be specified at the UI interface so that varied tests can |
---|
11 | be run on solids with different parameters without recompiling |
---|
12 | the code. |
---|
13 | |
---|
14 | 2. Log file. Errors are listed in a log file for later study. |
---|
15 | |
---|
16 | 3. Debugging. Errors in a log file can be recreated for later |
---|
17 | offline debugging. |
---|
18 | |
---|
19 | 4. Visualization. Errors in a log file can be recreated offline |
---|
20 | for visual display, as an aid in debugging. |
---|
21 | |
---|
22 | 5. Grids. There is an option to create test trajectories and |
---|
23 | points along discrete points in space, to test errors at the |
---|
24 | exact intersections with solid edges and corners. |
---|
25 | |
---|
26 | |
---|
27 | Installation |
---|
28 | ------------ |
---|
29 | |
---|
30 | The standard make file included with SBT links against the full geant4 |
---|
31 | libraries (much like a geant4 application). |
---|
32 | |
---|
33 | It should be possible to produce a makefile that only requires a |
---|
34 | subset of libraries, but this makefile is not supplied in the package. |
---|
35 | |
---|
36 | SBT has been tested on SUN-CC and Linux platforms. |
---|
37 | |
---|
38 | |
---|
39 | General (Interactive) Use |
---|
40 | ------------------------- |
---|
41 | |
---|
42 | The general use of SBT involves the following commands: |
---|
43 | 1. Choosing a solid (with a "/solid/" command) |
---|
44 | 2. Specifying geometry test parameters (with a "/test/" command) |
---|
45 | 3. Running the geometry test (with command "/test/run") |
---|
46 | 4. Specifying voxel test parameters (with a "/voxel/" command) |
---|
47 | 5. Running the voxel test (with command "/voxel/run") |
---|
48 | 6. Repeating as desired |
---|
49 | |
---|
50 | Example session: |
---|
51 | |
---|
52 | /solid/G4Polycone 0 360 4 (1.0,1.2,1.4,1.2) (-1.0,-1.0,1.0,1.0) |
---|
53 | /test/maxPoints 100 |
---|
54 | /test/errorFileName mylogfile.log |
---|
55 | /test/run |
---|
56 | |
---|
57 | |
---|
58 | Batch Jobs |
---|
59 | ---------- |
---|
60 | |
---|
61 | geant4 command scripts for some solids are supplied. They are given |
---|
62 | names <solid>.geant4, e.g. "box.geant4" and "polycone.geant4". Each |
---|
63 | script attempts to run a comprehensive test using several variations |
---|
64 | of each solid, with and without discrete test points. When used they |
---|
65 | produce several log files. The log file are given the names |
---|
66 | <solid>.<test>.log, e.g. "box.a1.log". |
---|
67 | |
---|
68 | The Unix script "runSBT" is included to do the following: |
---|
69 | 1. Run SBT using a geant4 script |
---|
70 | 2. Tally up in one line the total number of |
---|
71 | reported errors in all log files |
---|
72 | |
---|
73 | |
---|
74 | Method: geometry |
---|
75 | ---------------- |
---|
76 | |
---|
77 | SBT creates a set of random points in 3D space, in a Gaussian distribution |
---|
78 | with adjustable mean and width in each dimension. The default is to |
---|
79 | generate points with a distribution centered at zero and with a width |
---|
80 | of 1 meter. This is appropriate for solids of dimensions of roughly 1 |
---|
81 | meter on each side. |
---|
82 | |
---|
83 | Adjustments of the mean is possible with the "/test/target" command |
---|
84 | and the widths with the "/test/widths" command. Adjustment of these |
---|
85 | parameters are generally not necessary if enough points are generated |
---|
86 | but may be desirable in order to make the test more efficient. |
---|
87 | Adjustment of the mean may also be desirable for discrete points |
---|
88 | (see description later in this file). |
---|
89 | |
---|
90 | For each generated point, SBT first asks the target solid if the |
---|
91 | point is inside, outside, or on the surface of the solid. Depending |
---|
92 | on the answer, the point is added to a corresponding list of points. |
---|
93 | Each of the three lists (of inside, outside, or surface points) contains |
---|
94 | at most 100 points. If a new point is added to a list that already |
---|
95 | contains 100 points, it replaces an existing point chosen at random. |
---|
96 | The limitation of 100 points is intended to keep SBT running roughly |
---|
97 | in a CPU time of roughly proportional to the total number of |
---|
98 | points generated. |
---|
99 | |
---|
100 | After being added to its list, each inside point is tested |
---|
101 | against all of the points on the outside list. Similarly, each |
---|
102 | outside point is tested against all of the points on the inside list. |
---|
103 | At the moment, no tests are performed on the surface points. |
---|
104 | The tests are described in more detail below. |
---|
105 | |
---|
106 | Any error encountered is written to a log file. The name of the log |
---|
107 | file by default is "sbt.log", and can be changed with the |
---|
108 | "/test/errorFileName" command. The format of the log file is |
---|
109 | described in more detail below. To prevent flooding of the log file |
---|
110 | by one type of error, if the same error is uncovered more than five |
---|
111 | times, any remaining such errors are suppressed in the log file. |
---|
112 | |
---|
113 | SBT finishes its test when one of the following conditions are met: |
---|
114 | |
---|
115 | 1. The total number of random points reaches a maximum |
---|
116 | 2. The total number of errors reported reaches a maximum |
---|
117 | |
---|
118 | Value (1) defaults to 10000 points and is set by command "/test/maxPoints". |
---|
119 | Value (2) defaults to 100 errors in the log file and is set by |
---|
120 | command "/test/maxErrors". |
---|
121 | |
---|
122 | |
---|
123 | Method: voxel |
---|
124 | ------------- |
---|
125 | |
---|
126 | To start a voxel test, SBT first generates up to 100000 random |
---|
127 | points until it finds 1000 points inside the solid (using method |
---|
128 | G4VSolid::Inside). |
---|
129 | |
---|
130 | Afterwards, it starts generating random voxels. It does this by |
---|
131 | throwing a random number for each x,y,z dimension. If this |
---|
132 | number is less than 0.2, this coordinate is given no limits. |
---|
133 | Otherwise, the remaining 0.8 is spread between +/- the range specified |
---|
134 | in command /voxel/widths (default value is 1 meter). |
---|
135 | |
---|
136 | For each random voxel, 20 random offsets are choosen. For these |
---|
137 | 20 offsets in addition to no offset, the following rotations are tried: |
---|
138 | |
---|
139 | 1. No rotation |
---|
140 | 2. Random rotation around z |
---|
141 | 3. A further random rotation around x |
---|
142 | 4. A further random rotation around y |
---|
143 | 5. A further random rotation around z |
---|
144 | |
---|
145 | So, each random sized voxel is tested under 21*5 = 105 different |
---|
146 | offsets and rotation. |
---|
147 | |
---|
148 | Each voxel test consists of calling G4VSolid::CalculateExtent for |
---|
149 | each of the three coordinate axes. |
---|
150 | |
---|
151 | For each axis, if CalculateExtent returns false, the following tests |
---|
152 | are performed: |
---|
153 | |
---|
154 | 1. Make sure none of the 1000 points inside the solid |
---|
155 | (found earlier) are inside the voxel. |
---|
156 | |
---|
157 | Otherwise, if CalculateExtent returns true, the following tests are |
---|
158 | performed: |
---|
159 | |
---|
160 | 1. Make sure all 1000 of the points inside the solid |
---|
161 | (found earlier) are inside the limits returned. |
---|
162 | |
---|
163 | 2. Make sure the min limit is smaller or equal to the max limit. |
---|
164 | |
---|
165 | 3. Make sure the min and max limits are not outside the |
---|
166 | original voxel limits (if there were any) |
---|
167 | |
---|
168 | 4. Calculate the set of points spread in the following |
---|
169 | pattern: |
---|
170 | |
---|
171 | 1----2----3 |
---|
172 | | | | |
---|
173 | | | | |
---|
174 | 4----5----6 |
---|
175 | | | | |
---|
176 | | | | |
---|
177 | 7----8----9 |
---|
178 | |
---|
179 | along the two axes not being tested to the current |
---|
180 | voxel limits along those two axes, or to +/- 10 meters |
---|
181 | if the voxel is not limit only an axis. These nine points |
---|
182 | are positions at the min and max points in the voxel. |
---|
183 | SBT then uses G4VSolid::Inside to check whether the |
---|
184 | points are outside or on the surface of the solid. |
---|
185 | |
---|
186 | |
---|
187 | Choosing the Target Solid |
---|
188 | ------------------------ |
---|
189 | |
---|
190 | The following commands are available for creating solids: |
---|
191 | |
---|
192 | /solid/G4Box <dx> <dy> <dz> |
---|
193 | |
---|
194 | /solid/G4Para <dx> <dy> <dz> <alpha> <theta> <phi> |
---|
195 | |
---|
196 | /solid/G4Trap <dz> <theta> <phi> <dy1> <dx1> <dx2> <alpha1> <dy2> <dx3> <dx4> <alpha2> |
---|
197 | |
---|
198 | /solid/G4Trd <dx1> <dx2> <dy1> <dy2> <dz> |
---|
199 | |
---|
200 | /solid/G4Sphere <rmin> <rmax> <startPhi> <deltaPhi> <startTheta> <deltaTheta> |
---|
201 | |
---|
202 | /solid/G4Torus <rmin> <rmax> <rtorus> <startPhi> <deltaPhi> |
---|
203 | |
---|
204 | /solid/G4Tubs <rmin> <rmax> <dz> <startPhi> <deltaPhi> |
---|
205 | |
---|
206 | /solid/G4Cons <rmin1> <rmax1> <rmin2> <rmax2> <dz> <startPhi> <deltaPhi> |
---|
207 | |
---|
208 | /solid/G4Hype <innerRadius> <outerRadius> <innerStereo> <outerStereo> <dz> |
---|
209 | |
---|
210 | /solid/G4Polycone <phiStart> <phiTotal> <numRZ> <r[]> <z[]> |
---|
211 | |
---|
212 | /solid/G4Polyhedra <phiStart> <phiTotal> <numSides> <numRZ> <r[]> <z[]> |
---|
213 | |
---|
214 | Units are always meters and degrees. |
---|
215 | |
---|
216 | The arrays r[] and z[] have the following syntax: |
---|
217 | |
---|
218 | (<value1>[,<values2>...]) | (-) |
---|
219 | |
---|
220 | where *no spaces are allowed*. The special array "(-)" is the empty array. |
---|
221 | |
---|
222 | Examples: |
---|
223 | |
---|
224 | /solid/G4Box 1 1 1 |
---|
225 | |
---|
226 | /solid/G4Tubs 0.8 1 1 0 90 |
---|
227 | |
---|
228 | /solid/G4Polycone 0 90 4 (1.0,1.2,1.4,1.2) (-1.0,-1.0,1.0,1.0) |
---|
229 | |
---|
230 | |
---|
231 | Log File Format: geometry test |
---|
232 | ------------------------------ |
---|
233 | |
---|
234 | The log file is an ASCII file delimited by newlines. Each line |
---|
235 | that begins with "%" is a comment. Other lines have the format: |
---|
236 | |
---|
237 | <error number> <p.x> <p.y> <p.z> <v.x> <v.y> <v.z> |
---|
238 | |
---|
239 | where p is the position and v is the (unit) direction most closely |
---|
240 | associated with the error. Before each such error line, SBT adds |
---|
241 | a comment describing the error. In addition SBT adds comments |
---|
242 | concerning the test at the beginning and end of the file. |
---|
243 | |
---|
244 | The meaning of the specific errors are described below. |
---|
245 | |
---|
246 | |
---|
247 | Log File Format: voxel test |
---|
248 | --------------------------- |
---|
249 | |
---|
250 | The log file from the voxel test is not made to be machine readable, |
---|
251 | since the types of errors from this test are too varied. Instead, |
---|
252 | for each error the word "ERROR" is displayed, and a description of the |
---|
253 | error follows. The voxel and transform parameters are then displayed. |
---|
254 | |
---|
255 | |
---|
256 | Testing Inside Points |
---|
257 | --------------------- |
---|
258 | |
---|
259 | See routine SBTrun::TestInsidePoint in file src/SBTrun.cc. |
---|
260 | |
---|
261 | Each inside point is tested against all points in the outside list. |
---|
262 | The tests are, in order: |
---|
263 | |
---|
264 | 1. DistanceToOut(p) is invoked, where p is the inside point being |
---|
265 | tested. The result must be greater than 0, or the following |
---|
266 | error is issued in the log file: |
---|
267 | |
---|
268 | "TI: DistanceToOut(p) <= 0" |
---|
269 | |
---|
270 | 2. The vector v is calculated from the inside point to the |
---|
271 | next point in the list of outside points. DistanceToOut(p,v,...) |
---|
272 | is then invoked. The value must be greater than zero or |
---|
273 | the following error is issued: |
---|
274 | |
---|
275 | "TI: DistanceToOut(p,v) <= 0" |
---|
276 | |
---|
277 | The result must not be "kInfinity" or the following error is issued: |
---|
278 | |
---|
279 | "TI: DistanceToOut(p,v) == kInfinity" |
---|
280 | |
---|
281 | The result must not be less than the value from step (1), |
---|
282 | or the following error is issued: |
---|
283 | |
---|
284 | "TI: DistanceToOut(p,v) < DistanceToIn(p)" |
---|
285 | |
---|
286 | 3. If the normal returned by step (2) is valid, the dot product |
---|
287 | of the normal and v must be greater than zero, or the |
---|
288 | following error is issued: |
---|
289 | |
---|
290 | "TI: Outgoing normal incorrect" |
---|
291 | |
---|
292 | 4. A new point p2 = p + dist*v is calculated, where dist is the |
---|
293 | value found in step (2). Inside(p2) is then invoked. If the |
---|
294 | results is "kInside", the following error is issued: |
---|
295 | |
---|
296 | "TI: DistanceToOut(p,v) undershoots" |
---|
297 | |
---|
298 | If the result is "kOutside", the following error is issued: |
---|
299 | |
---|
300 | "TI: DistanceToOut(p,v) overshoots" |
---|
301 | |
---|
302 | In both cases, the value of p is stored in the log file (not p2). |
---|
303 | |
---|
304 | 5. DistanceToIn(p2) is invoked. If the result is not *exactly* zero, |
---|
305 | the following error is issued: |
---|
306 | |
---|
307 | "T02: DistanceToIn(p) should be zero" |
---|
308 | |
---|
309 | 6. DistanceToOut(p2) is invoked. If the result is not *exactly* zero, |
---|
310 | the following error is issued: |
---|
311 | |
---|
312 | "T02: DistanceToOut(p) should be zero" |
---|
313 | |
---|
314 | 7. DistanceToIn(p2,v) is invoked. If the result is not *exactly* zero, |
---|
315 | the following error is issued: |
---|
316 | |
---|
317 | "T02: DistanceToIn(p,v) should be zero" |
---|
318 | |
---|
319 | 8. DistanceToOut(p2,v,...) is invoked. If the result is zero, we have |
---|
320 | encountered the deadlock condition (track passing through a |
---|
321 | corner) that currently plagues the CSG solid specifications. |
---|
322 | The test on this particular outside point is suspended, and step |
---|
323 | (2) is skipped to for the next outside point on the list. |
---|
324 | |
---|
325 | If the result is "kInfinity", the following error is issued: |
---|
326 | |
---|
327 | "T02: DistanceToOut(p,v) == kInfinity" |
---|
328 | |
---|
329 | 9. If the normal calculated in step (8) is valid, the dot product |
---|
330 | of the normal and v must be greater than zero, or the following |
---|
331 | error is issued: |
---|
332 | |
---|
333 | "T02: Outgoing normal incorrect" |
---|
334 | |
---|
335 | 10. The vector p3 = p2 + dist*v is calculated, where dist is the |
---|
336 | value returned in step 8. Inside(p3) is then invoked. If the |
---|
337 | result is "kInside", the following error is issued: |
---|
338 | |
---|
339 | "T02: DistanceToOut(p,v) undershoots" |
---|
340 | |
---|
341 | If the result is "kOutside", the following error is issued: |
---|
342 | |
---|
343 | "TO2: DistanceToOut(p,v) overshoots" |
---|
344 | |
---|
345 | 11. If the result of step (8) has a valid normal, DistanceToIn(p3,v) |
---|
346 | is invoked. If the result is not "kInfinity", the following |
---|
347 | error is issued: |
---|
348 | |
---|
349 | "TO2: DistanceToOut incorrectly returns validNorm==true (line of sight)" |
---|
350 | |
---|
351 | (validNorm is to be returned true only if the solid is entirely |
---|
352 | behind the surface being exited.) |
---|
353 | |
---|
354 | 12. If the result of step (8) has a valid normal, the vector |
---|
355 | p3top = pi - p3 is calculated for all points pi on the inside list. |
---|
356 | The dot production of p3top with the normal (from step (8)) is |
---|
357 | then calculated. If this dot product for any inside point |
---|
358 | is positive, then the following error is issued: |
---|
359 | |
---|
360 | "T02: DistanceToOut incorrectly returns validNorm==true (horizon)" |
---|
361 | |
---|
362 | (validNorm is to be returned true only if the solid is entirely |
---|
363 | behind the plane perpendicular to the normal at the exit point.) |
---|
364 | |
---|
365 | |
---|
366 | Testing Outside Points |
---|
367 | ---------------------- |
---|
368 | |
---|
369 | See routine SBTrun::TestOutsidePoint in file src/SBTrun.cc. |
---|
370 | |
---|
371 | Each outside point is tested against all points in the inside list. |
---|
372 | The test are, in order: |
---|
373 | |
---|
374 | 1. DistanceToIn(p) is invoked, where p is the target outside |
---|
375 | point. The result must be greater than zero, or the following |
---|
376 | error is issued: |
---|
377 | |
---|
378 | "T0: DistanceToIn(p) <= 0" |
---|
379 | |
---|
380 | 2. The vector v is calculated from the outside point to the |
---|
381 | next point in the list of inside points. DistanceToIn(p,v) |
---|
382 | is then invoked. The value must be greater than zero or |
---|
383 | the following error is issued: |
---|
384 | |
---|
385 | "T0: DistanceToIn(p,v) <= 0" |
---|
386 | |
---|
387 | The result must not be "kInfinity", or the following error |
---|
388 | is issued: |
---|
389 | |
---|
390 | "T0: DistanceToIn(p,v) == kInfinity" |
---|
391 | |
---|
392 | The result must be greater than the value from step (1), |
---|
393 | or the following error is issued: |
---|
394 | |
---|
395 | "T0: DistanceToIn(p,v) < DistanceToIn(p)" |
---|
396 | |
---|
397 | 3. A new point p2 = p + dist*v is calculated, where dist is the |
---|
398 | value found in step (2). Inside(p2) is then invoked. If the |
---|
399 | results is "kOutside", the following error is issued: |
---|
400 | |
---|
401 | "TO: DistanceToOut(p,v) undershoots" |
---|
402 | |
---|
403 | If the result is "kInside", the following error is issued: |
---|
404 | |
---|
405 | "TO: DistanceToOut(p,v) overshoots" |
---|
406 | |
---|
407 | In both cases, the value of p is stored in the log file (not p2). |
---|
408 | |
---|
409 | |
---|
410 | Discrete Points |
---|
411 | --------------- |
---|
412 | |
---|
413 | There is an option of generating random points on a grid. The origin |
---|
414 | of the grid always corresponds to the mean value (as set by "/test/target"). |
---|
415 | The spacing of the grid is adjusted by command "/test/gridSizes". |
---|
416 | |
---|
417 | |
---|
418 | Debugging: geometry |
---|
419 | ------------------- |
---|
420 | |
---|
421 | Once a test is run and a log file created, it is possible to read the |
---|
422 | values from the log file to recreate an error. This is useful in the |
---|
423 | debugger to discover the precise reason for the error. |
---|
424 | |
---|
425 | No check is made that the current solid is identical to the solid |
---|
426 | used to make the log file. It is up to the user to ensure this |
---|
427 | (using the appropriate "/solid/" command if necessary). |
---|
428 | |
---|
429 | NOTE: |
---|
430 | This has changed. The current solid is written in the log file |
---|
431 | So the ErrorView script could convert a log file to a visualization |
---|
432 | script that could be run by SBT. |
---|
433 | |
---|
434 | The following commands are supported: |
---|
435 | |
---|
436 | 1. /test/draw <error number> |
---|
437 | |
---|
438 | Draw the error and the solid (if possible) using the currently |
---|
439 | selected visualization. |
---|
440 | |
---|
441 | 2. /test/debugInside <error number> |
---|
442 | |
---|
443 | Invokes the "Inside" method of the test solid. |
---|
444 | |
---|
445 | 3. /test/debugToInP <error number> |
---|
446 | |
---|
447 | Invokes the "DistanceToIn(p)" method of the test solid. |
---|
448 | |
---|
449 | 4. /test/debugToInPV <error number> |
---|
450 | |
---|
451 | Invokes the "DistanceToIn(p,v)" method of the test solid. |
---|
452 | A new point p2 = p + dist*v is calculated, and then the |
---|
453 | "Inside" method is invoked for that point. |
---|
454 | |
---|
455 | 5. /test/debugToOutP <error number> |
---|
456 | |
---|
457 | Invokes the "DistanceToOut(p)" method of the test solid. |
---|
458 | |
---|
459 | 6. /test/debugToOutPV <error number> |
---|
460 | |
---|
461 | Invokes the "DistanceToOut(p,v,...)" method of the test solid. |
---|
462 | A new point p2 = p + dist*v is calculated, and then the |
---|
463 | "Inside" method is invoked for that point. |
---|
464 | |
---|
465 | These commands are intended to be in combination with a debugger (such |
---|
466 | as dbx). To debug a particular error, one sets a break point in the |
---|
467 | relevant routine(s) and issues the appropriate "/test/" command. |
---|
468 | The "/test/draw" command may be useful to isolate the problem. |
---|
469 | |
---|
470 | Clearly, to use the debugger requires that the geant4 libraries linked |
---|
471 | to SBT are compiled with the debug flag on (environment variable G4DEBUG). |
---|
472 | |
---|
473 | |
---|
474 | Debugging: voxel |
---|
475 | ---------------- |
---|
476 | |
---|
477 | Included in SBT is a package for displaying voxels and the |
---|
478 | results of ::CalculateExtent. The commands for this are under |
---|
479 | the tree /voxel/picture. |
---|
480 | |
---|
481 | 1. /voxel/picture/voxel |
---|
482 | |
---|
483 | Takes six double numbers (xmin xmax ymin ymax zmin zmax) |
---|
484 | to specify the voxel dimensions. If any min > max, that |
---|
485 | dimension is taken to be unlimited. |
---|
486 | |
---|
487 | 2. /voxel/picture/translate |
---|
488 | |
---|
489 | Takes three double numbers to specify the translation in |
---|
490 | the voxel. |
---|
491 | |
---|
492 | 4. /voxel/picture/rotate |
---|
493 | |
---|
494 | Takes four doubles numbers (axisx axisy axisz rotation) to |
---|
495 | specify the axis and rotation amount to specify the |
---|
496 | rotation of the voxel. |
---|
497 | |
---|
498 | 5. /voxel/picture/point |
---|
499 | |
---|
500 | Takes three numbers for an optional point to be displayed |
---|
501 | along with the voxel and solid shape. |
---|
502 | |
---|
503 | 6. /voxel/picture/limit |
---|
504 | |
---|
505 | Specifies the voxel limits to be drawn inside the |
---|
506 | voxel. |
---|
507 | |
---|
508 | 7. /voxel/picture/draw |
---|
509 | |
---|
510 | Draws the items as specified in the above 1-6 commands. |
---|
511 | |
---|
512 | 8. /voxel/picture/debug |
---|
513 | |
---|
514 | Invokes ::CalculateExtent and ::Inside for the items |
---|
515 | as specified in the above 1--6 commands. Useful |
---|
516 | for running the solid code inside a debugger. |
---|
517 | |
---|
518 | |
---|
519 | Problems |
---|
520 | -------- |
---|
521 | |
---|
522 | Visualization is used in a manner that may not be entirely consistent |
---|
523 | with its design. This may introduce errors. |
---|
524 | |
---|
525 | SBT uses the random number generator G4UniformRand. It does not appear |
---|
526 | that this random number generator is reproducible across platforms. |
---|
527 | |
---|
528 | Recovering an error from a log file sometimes does not reproduce the |
---|
529 | problem, presumably due to a subtle inaccuracy in translating the double |
---|
530 | values to and/or from the ASCII log file. This despite writing out |
---|
531 | 14 digits for the values in the ASCII log file. |
---|