1 | """ |
---|
2 | Summary |
---|
3 | ======= |
---|
4 | This macro provides a set of definitions which allow for automatic filter |
---|
5 | transmission and exposure time adjustments during experiments. |
---|
6 | |
---|
7 | Description |
---|
8 | =========== |
---|
9 | After each count command, the obtained counts are evaluated and checked for |
---|
10 | over-/under-exposure. In case of unsatisfactory count levels, filter |
---|
11 | transmissions and optionally exposure times are adjusted and exposures are |
---|
12 | repeated until a valid exposure is obtained. |
---|
13 | |
---|
14 | Exposure optimization modes |
---|
15 | --------------------------- |
---|
16 | Two different modes of operation are available to optimize the count levels |
---|
17 | for each exposure: |
---|
18 | |
---|
19 | - Post-exposure adjustments: Each new exposures is taken with settings that |
---|
20 | are based on the feedback obtained from the previous one. This mode is |
---|
21 | based on the assumption that the measured intensity profiles are only |
---|
22 | gradually changing, and that a satisfactory prediction of the change in |
---|
23 | the count levels can be obtained in most cases to yield a good exposure. |
---|
24 | In those cases where the predictions fail and the new exposure falls |
---|
25 | outside the acceptable limits, the settings are adjusted and the exposure |
---|
26 | is retaken immediately. |
---|
27 | - Pilot exposure: Each exposure is preceeded by a short pilot exposure, |
---|
28 | which is used to establish the count levels at the current positions. |
---|
29 | |
---|
30 | Both modes have their relative merits and drawbacks. Post-exposure |
---|
31 | adjustments are riskier in terms of overexposing a detector, since the |
---|
32 | feedback is obtained only after potentially very long exposures. On the |
---|
33 | other hand, they are more efficient in terms of dead-time, especially when |
---|
34 | scanning signals that change only gradually. In this case, it is very |
---|
35 | seldomly necessary to repeat exposures. The pilot exposure mode, in |
---|
36 | contrast, is safer, since it detects potentially harmfully strong signals |
---|
37 | much faster. This comes at the cost of significantly increased dead-times, |
---|
38 | particularly for detectors with longer arming or readout times. |
---|
39 | |
---|
40 | Exposure optimization scheme |
---|
41 | ---------------------------- |
---|
42 | The filter and exposure time adjustments principles are based on the |
---|
43 | following criteria to formulate an adjustment strategy. Firstly, it is |
---|
44 | important to note that there are two separate effects which may cause an |
---|
45 | over-exposure of the detector: |
---|
46 | |
---|
47 | #. Paralizing the counter as a result of a count RATE which exceeds the |
---|
48 | ability of the detector to separate individual photons in time (only for |
---|
49 | single-photon-counting devices, does not apply to charge-integrating). |
---|
50 | #. Saturating the counter as a result of exceeding the maximum NUMBER OF |
---|
51 | COUNTS that can be stored in the counter. |
---|
52 | |
---|
53 | The incident photon RATE (case 1) can only be adjusted through the use of |
---|
54 | filters (attenuators), while the integrated NUMBER OF COUNTS is affected |
---|
55 | both by the filter transmission and the integration duration (count time). |
---|
56 | In this implementation, ensuring a valid photon RATE always takes |
---|
57 | precedence over any other adjustment. Once the rate has been optimized |
---|
58 | (keeping it within a given band below the saturation threshold), the |
---|
59 | exposure times may be adjusted. See the next sections below for details. |
---|
60 | |
---|
61 | Filter tramsmission adjustments (RATE) |
---|
62 | ---------------------------------------- |
---|
63 | The filter adjustment assures a high incident photon rate within a band |
---|
64 | just below the rate limit of the detector. The width of the band is |
---|
65 | defined by the step size in transmission, defined in AUTO_FILTER_FACTOR, |
---|
66 | which is used for each correction. If the count rate is higher than |
---|
67 | AUTO_RATE_LIMIT, the transmission is immediately reduced by |
---|
68 | AUTO_FILTER_FACTOR and the exposure is retaken. If the count rate is |
---|
69 | lower than AUTO_RATE_LIMIT/(2*AUTO_FILTER_FACTOR), the change in |
---|
70 | transmission required to reach a count rate of 0.75*AUTO_RATE_LIMIT is |
---|
71 | calculated, the transmission increased by that factor and the exposure is |
---|
72 | retaken immediately. If the measured count rate falls between these limits, |
---|
73 | no change is applied to the filters. The following scheme illustrates |
---|
74 | this behavior:: |
---|
75 | |
---|
76 | Threshold levels Actions |
---|
77 | ---------------- ------- |
---|
78 | |
---|
79 | - decrease trasmission by AUTO_FILTER_FACTOR |
---|
80 | - retake exposure immediately |
---|
81 | AUTO_RATE_LIMIT--------------------------------------------------------- |
---|
82 | /\ |
---|
83 | || 2*AUTO_FILTER_FACTOR - leave filters as they are |
---|
84 | \/ |
---|
85 | ------------------------------------------------------------------------ |
---|
86 | - calculate change in transmission required to |
---|
87 | reach 0.75*AUTO_RATE_LIMIT |
---|
88 | - increase trasmission by this factor |
---|
89 | - retake exposure immediately |
---|
90 | |
---|
91 | |
---|
92 | Exposure time adjustments (integrated NUMBER OF COUNTS) |
---|
93 | --------------------------------------------------------- |
---|
94 | Exposure time adjustments are designed with maximum efficiency in mind. |
---|
95 | The general idea is to attempt to maintain the integrated count level as |
---|
96 | close as possible to the user-defined AUTO_COUNT_TARGET, but to minimize |
---|
97 | the number of re-exposures by accepting exposures which fall into an |
---|
98 | "acceptable" count range, which is defined as any count level between |
---|
99 | the detectors saturation count AUTO_COUNT_HIGH and a user-defined |
---|
100 | lower count level AUTO_COUNT_LOW. If the exposure is within this |
---|
101 | acceptable band, a new count time to reach the target level is |
---|
102 | calculated based on the current exposure, but only applied to the next |
---|
103 | exposure in an attempt to predict a change in the right direction. If the |
---|
104 | current exposure falls outside the acceptable count range, the expsoure |
---|
105 | time is adjusted and the exposure is retaken immediately. Note that |
---|
106 | chosing a small acceptable range will thus result in retaking many |
---|
107 | exposures, hence increasing scan times. |
---|
108 | Count times will be adjusted between user-defined limits AUTO_EXP_LOW and |
---|
109 | AUTO_EXP_HIGH and rounded to a user-defined precision AUTO_COUNT_PREC. |
---|
110 | |
---|
111 | The diagram below outlines the measures taken when the registered maximum |
---|
112 | NUMBER OF COUNTS falls into the various defined ranges:: |
---|
113 | |
---|
114 | Threshold levels Actions |
---|
115 | ---------------- ------- |
---|
116 | |
---|
117 | - reduce exposure time (if > minimum time) |
---|
118 | - retake exposure immediately |
---|
119 | AUTO_COUNT_HIGH--------------------------------------------------------- |
---|
120 | - reduce exposure time (if > minimum time) |
---|
121 | - apply only to next exposure |
---|
122 | AUTO_COUNT_TARGET------------------------------------------------------- |
---|
123 | - increase exposure time (if < maximum time) |
---|
124 | - apply only to next exposure |
---|
125 | AUTO_COUNT_LOW---------------------------------------------------------- |
---|
126 | - increase exposure time (if < maximum time) |
---|
127 | - retake exposure immediately |
---|
128 | |
---|
129 | |
---|
130 | Configuration |
---|
131 | ============= |
---|
132 | |
---|
133 | No special configuration is needed to run these macros. Simply load the macro |
---|
134 | file and run :spec:def:`auto_setup`:: |
---|
135 | |
---|
136 | > qdo auto.mac |
---|
137 | > auto_setup |
---|
138 | |
---|
139 | Dependencies |
---|
140 | ------------ |
---|
141 | |
---|
142 | Dependencies on other macros: |
---|
143 | |
---|
144 | * ``filter.mac`` (used to control the attenuators): |
---|
145 | |
---|
146 | - :spec:def:`filter_trans` |
---|
147 | - :spec:def:`filter_get_trans()` |
---|
148 | - :spec:def:`filter_get_trans_up()` |
---|
149 | - :spec:def:`filter_get_mask()` |
---|
150 | - :spec:def:`filter_max()` |
---|
151 | |
---|
152 | * :spec:def:`recount` (modified count command used to retake an exposure) |
---|
153 | |
---|
154 | Impact |
---|
155 | ------ |
---|
156 | The following chained macro definitions are affected by this macro: |
---|
157 | |
---|
158 | * :spec:def:`user_prescan_head` |
---|
159 | * :spec:def:`user_chk_counts` (from our modified :spec:def:`count` command) |
---|
160 | * :spec:def:`user_precount` |
---|
161 | |
---|
162 | File information |
---|
163 | ================ |
---|
164 | |
---|
165 | Authors |
---|
166 | ------- |
---|
167 | * C.M. Schlepuetz (CS, cschlep), |
---|
168 | Argonne National Laboratory, cschlep@aps.anl.gov |
---|
169 | * Y. Yang (YY, ysyang), |
---|
170 | University of Michigan, ysyang@umich.edu |
---|
171 | |
---|
172 | Creation date |
---|
173 | ------------- |
---|
174 | 2011/02/25 |
---|
175 | |
---|
176 | Copyright |
---|
177 | --------- |
---|
178 | Copyright 2010 by the above authors (see AUTHOR/AUTHORS) |
---|
179 | |
---|
180 | This program is free software: you can redistribute it and/or modify |
---|
181 | it under the terms of the GNU General Public License as published by |
---|
182 | the Free Software Foundation, either version 3 of the License, or |
---|
183 | (at your option) any later version. |
---|
184 | |
---|
185 | This program is distributed in the hope that it will be useful, |
---|
186 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
187 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
188 | GNU General Public License for more details. |
---|
189 | |
---|
190 | You should have received a copy of the GNU General Public License |
---|
191 | along with this program. If not, see http://www.gnu.org/licenses/. |
---|
192 | |
---|
193 | Version |
---|
194 | ------- |
---|
195 | :: |
---|
196 | |
---|
197 | $Date: 2011-04-11 13:17:13 -0400 (Mon, 11 Apr 2011) $ |
---|
198 | $Author: cschlep $ |
---|
199 | $URL: file:///data/svn/software/spec/trunk/common/auto.mac $ |
---|
200 | $Revision: 25 $ |
---|
201 | |
---|
202 | |
---|
203 | Change log |
---|
204 | ---------- |
---|
205 | 2011/02/25 (CS, YY): |
---|
206 | |
---|
207 | - completely reworked previous versions of ``auto.mac`` to produce this new |
---|
208 | version: |
---|
209 | |
---|
210 | * improved efficiency |
---|
211 | * simplified code |
---|
212 | * new method of scaling the count times (see description above) |
---|
213 | |
---|
214 | 2011/04/04 (CS): |
---|
215 | |
---|
216 | - cleaned up code further |
---|
217 | - added and updated documentation |
---|
218 | - added ``auto_setup`` macro |
---|
219 | - added AUTO_AREADETECTOR_VERSION global to track which version of |
---|
220 | areaDetector is used in ``auto_init_analysis``. |
---|
221 | - added ``auto_on`` and ``auto_off`` |
---|
222 | - changed all macro names to lower case and underscore naming convention |
---|
223 | - changed all calls to macros from ``filter.mac`` to lower case and underscore |
---|
224 | naming conventions. |
---|
225 | |
---|
226 | 2011/04/11 (CS): |
---|
227 | |
---|
228 | - changed ``auto_prescan_header``: if AUTO_LEVEL > 1, set the exposure times to |
---|
229 | the minimum exposure time to start with. |
---|
230 | |
---|
231 | 2012/03/29 (CS): |
---|
232 | |
---|
233 | - modified code documentation to be compatible with the ROBODoc |
---|
234 | documentation generation software. |
---|
235 | - monitor a configurable SPEC counter rather than an EPICS channel for the |
---|
236 | adjustments. This allows for the monitoring of any arbitrary counter in |
---|
237 | SPEC, but requires that whatever signal is to be monitored is captured in |
---|
238 | a SPEC counter during the count process. |
---|
239 | - reworked the setup routines for easier use. |
---|
240 | - removed unnecessary ``auto_init_analysis`` |
---|
241 | - removed unnecessary AUTO_AREADETECTOR_VERSION global variable |
---|
242 | - renamed many variables for improved consistency |
---|
243 | |
---|
244 | 2012/04/23 (CS): |
---|
245 | |
---|
246 | - fixed a bug where long exposures with valid rate but saturating the |
---|
247 | counter would result in an infinite loop. |
---|
248 | |
---|
249 | 2012/07/06 (CS): |
---|
250 | |
---|
251 | - changed code documentation to be compatible with the new SPEC domain for the |
---|
252 | SPHINX code documentation suite. |
---|
253 | |
---|
254 | 2012/07/13 (CS): |
---|
255 | |
---|
256 | - renamed some private macros to start with underscores:: |
---|
257 | |
---|
258 | auto_precount --> _auto_precount |
---|
259 | auto_prescan_head --> _auto_prescan_head |
---|
260 | auto_user_chk_counts --> _auto_user_chk_counts |
---|
261 | |
---|
262 | - moved the macro definitions for the above macros out of the |
---|
263 | :spec:def:`auto_set_level` macro to avoid unnecessary nested definitions. |
---|
264 | |
---|
265 | |
---|
266 | TO DO |
---|
267 | ----- |
---|
268 | |
---|
269 | - Extensive testing of the pilot exposure mode |
---|
270 | - complete documentation |
---|
271 | - insert hyperlinks into documentation |
---|
272 | |
---|
273 | """ |
---|
274 | |
---|
275 | ############################################################################### |
---|
276 | # Global variable definitions |
---|
277 | ############################################################################### |
---|
278 | |
---|
279 | global AUTO_MAC #: Save the name of this macro file |
---|
280 | global AUTO_LEVEL #: Type of adjustments {0,1,2} |
---|
281 | global AUTO_MODE #: Adjustment mode (pilot vs. post-exp) {0,1} |
---|
282 | global AUTO_COUNTER #: Counter to monitor |
---|
283 | global AUTO_COUNT_RBV #: Counter read back value (measured counts) |
---|
284 | global AUTO_RETRY_MAX #: Maximum number of retries |
---|
285 | global AUTO_EXP_LOW #: Low exposure time limit |
---|
286 | global AUTO_EXP_HIGH #: High exposure time limit |
---|
287 | global AUTO_PILOT_EXPTIME #: Exposure time for pilot exposures |
---|
288 | global AUTO_RATE_LIMIT #: High rate limit |
---|
289 | global AUTO_COUNT_HIGH #: High count limit |
---|
290 | global AUTO_COUNT_TARGET #: Target count level |
---|
291 | global AUTO_COUNT_LOW #: Low count limit |
---|
292 | global AUTO_FILTER_FACTOR #: Filter transmission factor for adjustments |
---|
293 | global AUTO_COUNT_PREC #: Count time precision (rounding) |
---|
294 | global AUTO_FILTER_LOCK #: Lock if rate-limited |
---|
295 | global AUTO_SET_PILOT #: Set pilot exposure time in user_precount |
---|
296 | global AUTO_ORIG_EXPTIME #: Save the original requested count time |
---|
297 | global AUTO_DEBUG #: Debug flag |
---|
298 | |
---|
299 | # set default values for global variables |
---|
300 | AUTO_MAC = DOFILE |
---|
301 | AUTO_COUNTER = det |
---|
302 | AUTO_LEVEL = 0 |
---|
303 | AUTO_MODE = 0 |
---|
304 | AUTO_RETRY_MAX = 20 |
---|
305 | AUTO_COUNT_HIGH = 5e5 |
---|
306 | AUTO_RATE_LIMIT =2e5 |
---|
307 | AUTO_COUNT_RBV = 1e6 |
---|
308 | AUTO_COUNT_TARGET = 1e4 |
---|
309 | AUTO_COUNT_LOW = 0.5 * AUTO_COUNT_TARGET |
---|
310 | AUTO_PILOT_EXPTIME = 0.05 |
---|
311 | AUTO_EXP_LOW = 1 |
---|
312 | AUTO_EXP_HIGH = 10 |
---|
313 | AUTO_FILTER_FACTOR = 5 |
---|
314 | AUTO_COUNT_PREC = 0.01 |
---|
315 | AUTO_FILTER_LOCK = 0 |
---|
316 | AUTO_SET_PILOT = 1 |
---|
317 | AUTO_DEBUG = 0 |
---|
318 | |
---|
319 | |
---|
320 | ############################################################################### |
---|
321 | # Macro command definitions |
---|
322 | ############################################################################### |
---|
323 | |
---|
324 | #------------------------------------------------------------------------------ |
---|
325 | # allow for misspelled help commands |
---|
326 | #def autohelp '{auto_help}' |
---|
327 | |
---|
328 | def auto_help '{ |
---|
329 | """ |
---|
330 | Displays the auto help text. |
---|
331 | |
---|
332 | Usage:: |
---|
333 | |
---|
334 | > auto_help |
---|
335 | |
---|
336 | .. note:: The help text is generated by simply displaying the text file |
---|
337 | ``auto_mac.txt``, which should reside in the same directory as |
---|
338 | ``auto.mac``. If the file does not exist, a generic help text defined in |
---|
339 | ``auto_help`` is shown. |
---|
340 | """ |
---|
341 | |
---|
342 | unix (sprintf ("dirname %s", AUTO_MAC), _1) |
---|
343 | ll = length (_1) |
---|
344 | if (substr (_1, ll, 1) == "\n") _1 = substr (_1, 1, (ll - 1)) |
---|
345 | file = sprintf ("%s/auto_mac.txt", _1) |
---|
346 | if (file_info (file, "-e")) { |
---|
347 | unix (sprintf ("cat %s", file)) |
---|
348 | } else { |
---|
349 | printf("\nMacros available in file auto.mac ($Revision: 25 $):\n") |
---|
350 | printf(" ========"\n) |
---|
351 | printf("\n") |
---|
352 | printf(" auto_help - creates this help text\n") |
---|
353 | printf(" auto_setup - setup automatic exposure control\n") |
---|
354 | printf(" auto_set_mode - set the auto-adjustment mode\n") |
---|
355 | printf(" auto_set_level - activate or deactivate automatic filter\n") |
---|
356 | printf(" and exposure setting\n") |
---|
357 | printf(" auto_on - turn auto exposure control ON (dialog)\n") |
---|
358 | printf(" auto_off - turn auto exposure control OFF\n") |
---|
359 | printf(" auto_set_exposure - define the shortest and longest exposure\n") |
---|
360 | printf(" time used in case of automatic exposure\n") |
---|
361 | printf(" setting\n") |
---|
362 | printf(" auto_show - display current auto exposure settings\n") |
---|
363 | printf(" auto_show_exposure - display current exposure time settings\n") |
---|
364 | } |
---|
365 | }' |
---|
366 | |
---|
367 | |
---|
368 | #------------------------------------------------------------------------------ |
---|
369 | def auto_setup '{ |
---|
370 | """ |
---|
371 | Set up the control parameters for the automatic filter and exposure |
---|
372 | adjustments. |
---|
373 | |
---|
374 | Description: |
---|
375 | |
---|
376 | The following parameters can be adjusted to fit the particular needs of an |
---|
377 | experiment or detector type (global variables holding these parameters and |
---|
378 | default values are given in brackets): |
---|
379 | |
---|
380 | * Auto level: the level of automatic adjustments to be performed. Three |
---|
381 | levels are currently available [AUTO_LEVEL = 0]: |
---|
382 | |
---|
383 | ===== ================================================================= |
---|
384 | Level Description |
---|
385 | ===== ================================================================= |
---|
386 | 0 No automatic adjustments are made |
---|
387 | 1 Only filters are adjusted, no exposure time adjustments |
---|
388 | 2 Both filters and exposure times are automatically adjusted |
---|
389 | ===== ================================================================= |
---|
390 | |
---|
391 | * Auto mode: the mode used to calculate/apply the adjustments. Two modes |
---|
392 | are available [AUTO_MODE = 0]: |
---|
393 | |
---|
394 | ==== ================================================================== |
---|
395 | Mode Description |
---|
396 | ==== ================================================================== |
---|
397 | 0 Post-exposure analysis: exposures are taken at normal settings and |
---|
398 | analyzed in retrospect. The exposure is only retaken if it is |
---|
399 | deemed unacceptable. Otherwise, the calculated adjustments are |
---|
400 | applied only to the next exposure. This mode is faster, but |
---|
401 | riskier in terms of over-exposing the detector for potentially |
---|
402 | much longer times. |
---|
403 | 1 Pilot exposure mode: A short pilot exposure is taken before each |
---|
404 | exposure to determine the correct filter and exposure time |
---|
405 | settings. This is safer in terms of identifying over-exposures |
---|
406 | quickly and provides optimized settings for each exposure, but |
---|
407 | comes at a considerable cost in additional dead time. The pilot |
---|
408 | exposure time is specified in AUTO_PILOT_EXPTIME. |
---|
409 | ==== ================================================================== |
---|
410 | |
---|
411 | * Counter to monitor: the SPEC counter mnemonic or number of the counter |
---|
412 | used to assess the validity of the exposure. Note that when using area |
---|
413 | detectors, it is necessary to monitor the count levels per pixel, as this |
---|
414 | the saturation conditions. In this case, there needs to be a counter |
---|
415 | configured that is monitoring the maximum count rate of all pixels within |
---|
416 | the relevant region of interest. [AUTO_COUNTER = det] |
---|
417 | |
---|
418 | * Count RATE high limit: the maximum count rate (counts per second) on |
---|
419 | the detector that is acceptable for the experiment. If the measured count |
---|
420 | rate is higher than this limit, filters will be inserted to lower the |
---|
421 | rate. [AUTO_RATE_LIMIT = 2.0e5] |
---|
422 | |
---|
423 | * Target count level: the desired count level for a "perfect" exposure. |
---|
424 | All adjustments applied to filter and/or count times aim to achieve this |
---|
425 | level. [AUTO_COUNT_TARGET = 1.0e4] |
---|
426 | |
---|
427 | * Count level low limit: The lower count limit for an acceptable exposure. |
---|
428 | If the measured level is below this, filters and exposure times will be |
---|
429 | adjusted (if possible) and the exposure retaken. |
---|
430 | [AUTO_COUNT_LOW = 5000] |
---|
431 | |
---|
432 | * Counter saturation limit: The upper count limit for an acceptable |
---|
433 | exposure. This should be chosen below the actual saturation level of the |
---|
434 | detector. If the measured level exceeds the saturation limit, filters and |
---|
435 | exposure times will be adjusted (if possible) and the exposure is |
---|
436 | repeated. |
---|
437 | [AUTO_COUNT_HIGH = 5.0e5] |
---|
438 | |
---|
439 | * Transmission step: The step in filter transmission to be taken when |
---|
440 | adjusting the filters. The specified step must be larger than the |
---|
441 | largest available incremet in transmission values of the experimental |
---|
442 | setup to ensure that the adjustments can be successful. Ideally, this |
---|
443 | number is chosen anywhere between 2 and 10, but may need to be higher |
---|
444 | depending on the available filters. [AUTO_FILTER_FACTOR = 5] |
---|
445 | |
---|
446 | * Minimum exposure time: Minimum allowable exposure time to be used whith |
---|
447 | automatic exposure time adjustments. [AUTO_EXP_LOW = 1] |
---|
448 | |
---|
449 | * Maximum exposure time: Maximum allowable exposure time to be used whith |
---|
450 | automatic exposure time adjustments. [AUTO_EXP_HIGH = 10] |
---|
451 | |
---|
452 | * Pilot exposure time: Exposure time for the pilot exposure used in pilot |
---|
453 | mode. [AUTO_PILOT_EXPTIME = 0.05] |
---|
454 | |
---|
455 | * Count time precision: Automatically calculated count times will be |
---|
456 | rounded to this precision. Typically, a value of 0.01 or 0.001 seconds is |
---|
457 | recommended. [AUTO_COUNT_PREC = 0.01] |
---|
458 | |
---|
459 | * Maximum number of retries: The maximum number of retries to adjust |
---|
460 | exposure and filter settings before giving up. This avoids infinite loops |
---|
461 | due to inconsistent choices of control parameters. [AUTO_RETRY_MAX = 20] |
---|
462 | |
---|
463 | Usage:: |
---|
464 | |
---|
465 | > auto_setup |
---|
466 | then answer the questions |
---|
467 | |
---|
468 | """ |
---|
469 | |
---|
470 | local _setup_numitems, _setup_option, _tmp_option, _str1 |
---|
471 | |
---|
472 | # total number of setup items |
---|
473 | _setup_numitems = 13 |
---|
474 | |
---|
475 | _clear_screen |
---|
476 | |
---|
477 | _setup_option = 0 |
---|
478 | _tmp_option = -1 |
---|
479 | while (_tmp_option) { |
---|
480 | _tmp_option = -1 |
---|
481 | while (_tmp_option < 0 || _tmp_option > _setup_numitems){ |
---|
482 | _auto_print_setup |
---|
483 | _str1 = sprintf("Enter 1-%d to change the parameters, 0 to quit",\ |
---|
484 | _setup_numitems) |
---|
485 | _tmp_option = getval(_str1, _setup_option) |
---|
486 | if(index(_tmp_option, "q") == 1 || index(_tmp_option, "Q") == 1){ |
---|
487 | _tmp_option = 0 |
---|
488 | } |
---|
489 | } |
---|
490 | _setup_option = _tmp_option |
---|
491 | if (_setup_option != 0){ |
---|
492 | _auto_set_option _setup_option |
---|
493 | } |
---|
494 | _setup_option = (_tmp_option + 1)%(_setup_numitems + 1) |
---|
495 | } |
---|
496 | |
---|
497 | _auto_check_levels |
---|
498 | _auto_check_exposure |
---|
499 | |
---|
500 | }' |
---|
501 | |
---|
502 | |
---|
503 | #------------------------------------------------------------------------------ |
---|
504 | def auto_off '{ |
---|
505 | """ |
---|
506 | Turn off any automatic filter and exposure adjustments. |
---|
507 | |
---|
508 | USAGE:: |
---|
509 | |
---|
510 | > auto_off |
---|
511 | |
---|
512 | NOTE: |
---|
513 | This command is equivalent to ``auto_set_level 0`` |
---|
514 | |
---|
515 | SEE ALSO: |
---|
516 | :spec:def:`auto_set_level`, |
---|
517 | :spec:def:`auto_on` |
---|
518 | |
---|
519 | """ |
---|
520 | |
---|
521 | auto_set_level 0 |
---|
522 | |
---|
523 | }' |
---|
524 | |
---|
525 | |
---|
526 | #------------------------------------------------------------------------------ |
---|
527 | def auto_on '{ |
---|
528 | """ |
---|
529 | Turn on automatic filter and exposure adjustments. |
---|
530 | |
---|
531 | This macro is identical to :spec:def:`auto_set_level`. Please refer to the |
---|
532 | :spec:def:`auto_set_level` documentation for more details. |
---|
533 | """ |
---|
534 | |
---|
535 | auto_set_level $* |
---|
536 | |
---|
537 | }' |
---|
538 | |
---|
539 | #------------------------------------------------------------------------------ |
---|
540 | def auto_set_level '{ |
---|
541 | """ |
---|
542 | Set the level of automatic filter and exposure adjustments. |
---|
543 | |
---|
544 | USAGE:: |
---|
545 | |
---|
546 | > auto_set_level [<level>] |
---|
547 | > auto_on [<level>] |
---|
548 | |
---|
549 | If now arguement is given, the user is prompted for input. The argument |
---|
550 | ``<level>`` can be one of the following: |
---|
551 | |
---|
552 | ===== ================================================================= |
---|
553 | Level Description |
---|
554 | ===== ================================================================= |
---|
555 | ``0`` No automatic adjustments are made |
---|
556 | ``1`` Only filters are adjusted, no exposure time adjustments |
---|
557 | ``2`` Both filters and exposure times are automatically adjusted |
---|
558 | ===== ================================================================= |
---|
559 | |
---|
560 | EXAMPLES:: |
---|
561 | |
---|
562 | > auto_set_level |
---|
563 | then answer the questions in the dialogue |
---|
564 | |
---|
565 | > auto_on 1 |
---|
566 | turns on automatic filter adjustments (level 1) |
---|
567 | |
---|
568 | NOTE: |
---|
569 | :spec:def:`auto_set_level` and :spec:def:`auto_on` are equivalent to |
---|
570 | each other. |
---|
571 | |
---|
572 | SEE ALSO: |
---|
573 | :spec:def:`auto_off` |
---|
574 | |
---|
575 | """ |
---|
576 | |
---|
577 | if ($#>1){ |
---|
578 | eprint "Wrong number or illegal arguments in \'auto_set_level\'" |
---|
579 | eprint "Usage:" |
---|
580 | eprint " auto_set_level <level>" |
---|
581 | eprint "" |
---|
582 | eprint "<level> can be:" |
---|
583 | eprint "0 - OFF" |
---|
584 | eprint "1 - only automatic filter ON, automatic exposure OFF" |
---|
585 | eprint "2 - automatic filter and exposure ON" |
---|
586 | eprint "" |
---|
587 | exit |
---|
588 | } else if ($#>0){ |
---|
589 | AUTO_LEVEL = $1 |
---|
590 | } else { |
---|
591 | printf("Choose auto level:\n") |
---|
592 | printf(" 0 - automatic filter and exposure OFF\n") |
---|
593 | printf(" 1 - only automatic filter ON, automatic exposure OFF\n") |
---|
594 | printf(" 2 - automatic filter and exposure ON\n") |
---|
595 | AUTO_LEVEL = getval("Auto level", AUTO_LEVEL) |
---|
596 | } |
---|
597 | |
---|
598 | # check validity of AUTO_LEVEL |
---|
599 | if (!((AUTO_LEVEL==0) || (AUTO_LEVEL==1) || (AUTO_LEVEL==2))){ |
---|
600 | eprint "Illegal auto level in \'auto_set_level\'" |
---|
601 | eprint "Valid levels are:" |
---|
602 | eprint " 0 - OFF" |
---|
603 | eprint " 1 - only automatic filter ON, automatic exposure OFF" |
---|
604 | eprint " 2 - automatic filter and exposure ON" |
---|
605 | eprint "" |
---|
606 | } |
---|
607 | |
---|
608 | #-------------------------------------------- |
---|
609 | # include necessary chained macro definitions |
---|
610 | # depending on the current auto-level |
---|
611 | |
---|
612 | if (AUTO_LEVEL > 0){ |
---|
613 | |
---|
614 | #: add _auto_prescan_head to user_prescan_head |
---|
615 | cdef("user_prescan_head", "{_auto_prescan_head}; ", \ |
---|
616 | "auto_prescan_head_key", 0x10) |
---|
617 | |
---|
618 | #: add _auto_user_chk_counts to user_chk_counts |
---|
619 | cdef("user_chk_counts", "{_auto_user_chk_counts}; ", \ |
---|
620 | "auto_user_chk_counts_key") |
---|
621 | |
---|
622 | #: add _auto_precount to user_precount |
---|
623 | cdef("user_precount", "{_auto_precount}; ", "auto_precount_key", 0x10) |
---|
624 | |
---|
625 | #: add _auto_cleanup to the end of user_scan_tail |
---|
626 | cdef("user_scan_tail","{_auto_cleanup}; ", \ |
---|
627 | "auto_user_scan_tail_key",0x20) |
---|
628 | } |
---|
629 | |
---|
630 | #--------------------------------------------- |
---|
631 | # remove unnecessary chained macro definitions |
---|
632 | # depending on the current auto-level |
---|
633 | |
---|
634 | # Note: chained macro definitions which are not currently defined |
---|
635 | # can be deleted without producing an error. |
---|
636 | |
---|
637 | if (AUTO_LEVEL < 1) { |
---|
638 | |
---|
639 | #: remove _auto_prescan_head from user_prescan_head |
---|
640 | cdef("user_prescan_head", "", "auto_prescan_head_key", "delete") |
---|
641 | |
---|
642 | #: remove _auto_user_chk_counts from user_chk_counts |
---|
643 | cdef("user_chk_counts", "", "auto_user_chk_counts_key", "delete") |
---|
644 | |
---|
645 | #: remove _auto_precount from user_precount |
---|
646 | cdef("user_precount", "", "auto_precount_key", "delete") |
---|
647 | |
---|
648 | #: remove _auto_cleanup from user_scan_tail |
---|
649 | cdef("user_scan_tail", "", "auto_user_scan_tail_key", "delete") |
---|
650 | #: remove _auto_cleanup from cleanup_once |
---|
651 | cdef("cleanup_once", "", "auto_cleanup_once_key", "delete") |
---|
652 | } |
---|
653 | |
---|
654 | auto_show |
---|
655 | |
---|
656 | }' |
---|
657 | |
---|
658 | #------------------------------------------------------------------------------ |
---|
659 | def auto_set_mode '{ |
---|
660 | """ |
---|
661 | Set the acquisition mode to be used for the automatic filter and |
---|
662 | exposure time adjustments. |
---|
663 | |
---|
664 | DESCRIPTION: |
---|
665 | Need some more details here... |
---|
666 | |
---|
667 | USAGE:: |
---|
668 | |
---|
669 | > auto_set_mode [<mode>] |
---|
670 | where <mode> must be one of the following: |
---|
671 | 0 - post-exposure analysis |
---|
672 | 1 - pilot exposure mode |
---|
673 | when called with no arguments, the user is prompted |
---|
674 | |
---|
675 | EXAMPLE:: |
---|
676 | |
---|
677 | > auto_set_mode 1 |
---|
678 | use the pilot exposure mode for automatic adjustments. |
---|
679 | |
---|
680 | SEE ALSO: |
---|
681 | :spec:def:`auto_setup` |
---|
682 | |
---|
683 | """ |
---|
684 | |
---|
685 | local _mode |
---|
686 | |
---|
687 | if ( ($# != 1) && ($# != 0 )) { |
---|
688 | eprint "Wrong number or illegal arguments in \'auto_set_mode\'" |
---|
689 | eprint "Usage:" |
---|
690 | eprint " auto_set_mode <mode>" |
---|
691 | exit |
---|
692 | } else if ($# == 1){ |
---|
693 | _mode = $1 |
---|
694 | } else { |
---|
695 | _mode = getval("Enter the new auto mode", AUTO_MODE) |
---|
696 | } |
---|
697 | |
---|
698 | # check validity of mode |
---|
699 | if((AUTO_MODE != 0) & (AUTO_MODE !=1)){ |
---|
700 | eprint "ERROR: Illegal value for auto mode (%g)!" |
---|
701 | printf(" Auto mode is still %d\n", AUTO_MODE) |
---|
702 | exit |
---|
703 | } else { |
---|
704 | AUTO_MODE = _mode |
---|
705 | } |
---|
706 | |
---|
707 | auto_show |
---|
708 | |
---|
709 | }' |
---|
710 | |
---|
711 | |
---|
712 | #------------------------------------------------------------------------------ |
---|
713 | def auto_set_exposure '{ |
---|
714 | """ |
---|
715 | Set the maximum and minimum exposure times used for automatic exposure |
---|
716 | adjustments. |
---|
717 | |
---|
718 | USAGE:: |
---|
719 | |
---|
720 | > auto_set_exposure [<min> <max>] |
---|
721 | where <min> is the minimum and <max> the maximum exposure time [s] |
---|
722 | when called with no arguments, the user is prompted |
---|
723 | |
---|
724 | EXAMPLE:: |
---|
725 | |
---|
726 | > auto_set_exposure 1 10 |
---|
727 | set the minimum exposure time to 1 sec and the maximum to 10 sec |
---|
728 | |
---|
729 | """ |
---|
730 | |
---|
731 | if ( ($# != 2) && ($# != 0 )) { |
---|
732 | eprint "Wrong number or illegal arguments in \'auto_set_exposure\'" |
---|
733 | eprint "Usage:" |
---|
734 | eprint "auto_set_exposure [<min> <max>]" |
---|
735 | eprint "defines the minimum and maximum exposure times in seconds" |
---|
736 | eprint "(used if auto-level is set to 2 with \'auto_set_level\')" |
---|
737 | } else if ($# == 2){ |
---|
738 | AUTO_EXP_LOW = $1 |
---|
739 | AUTO_EXP_HIGH = $2 |
---|
740 | } else { |
---|
741 | AUTO_EXP_LOW = getval("Minimum exposure time [s]", AUTO_EXP_LOW) |
---|
742 | AUTO_EXP_HIGH = getval("Maximum exposure time [s]", AUTO_EXP_HIGH) |
---|
743 | } |
---|
744 | |
---|
745 | _auto_check_exposure |
---|
746 | auto_show_exposure |
---|
747 | |
---|
748 | }' |
---|
749 | |
---|
750 | |
---|
751 | #------------------------------------------------------------------------------ |
---|
752 | def auto_show '{ |
---|
753 | """ |
---|
754 | Display the current auto settings. |
---|
755 | |
---|
756 | USAGE:: |
---|
757 | |
---|
758 | > auto_show |
---|
759 | |
---|
760 | """ |
---|
761 | |
---|
762 | if (AUTO_LEVEL == 0) { |
---|
763 | printf("Auto-level has been set to %d.\n", AUTO_LEVEL) |
---|
764 | printf("Automatic filter setting is OFF.\n") |
---|
765 | printf("Automatic exposure setting is OFF.\n") |
---|
766 | } else if (AUTO_LEVEL == 1) { |
---|
767 | printf("Auto-level has been set to %d.\n", AUTO_LEVEL) |
---|
768 | printf("Automatic filter setting is ON.\n") |
---|
769 | printf("Automatic exposure setting is OFF.\n") |
---|
770 | } else if (AUTO_LEVEL == 2) { |
---|
771 | printf("Auto-level has been set to %d.\n", AUTO_LEVEL) |
---|
772 | printf("Automatic filter setting is ON.\n") |
---|
773 | printf("Automatic exposure setting is ON.\n") |
---|
774 | } else { |
---|
775 | AUTO_LEVEL = 0 |
---|
776 | printf("ERROR: Unknown auto-level - resetting to %d", AUTO_LEVEL) |
---|
777 | printf("Automatic filter setting is OFF.\n") |
---|
778 | printf("Automatic exposure setting is OFF.\n") |
---|
779 | } |
---|
780 | |
---|
781 | if(AUTO_MODE == 0){ |
---|
782 | printf("Auto mode is 0 (post-exposure adjustments)\n") |
---|
783 | } else if (AUTO_MODE == 1){ |
---|
784 | printf("Auto mode is 1 (pilot exposure)\n") |
---|
785 | } else { |
---|
786 | AUTO_MODE = 0 |
---|
787 | printf("ERROR: Unknown auto mode - resetting to %d", AUTO_MODE) |
---|
788 | } |
---|
789 | |
---|
790 | if(AUTO_LEVEL>1){ |
---|
791 | auto_show_exposure |
---|
792 | } |
---|
793 | |
---|
794 | }' |
---|
795 | |
---|
796 | |
---|
797 | #------------------------------------------------------------------------------ |
---|
798 | def auto_show_exposure '{ |
---|
799 | """ |
---|
800 | Display the current auto-level exposure settings. |
---|
801 | |
---|
802 | USAGE:: |
---|
803 | |
---|
804 | > auto_show_exposure |
---|
805 | |
---|
806 | """ |
---|
807 | |
---|
808 | printf("Exposure times: minimum = %g s, maximum = %g s\n",\ |
---|
809 | AUTO_EXP_LOW, AUTO_EXP_HIGH) |
---|
810 | |
---|
811 | }' |
---|
812 | |
---|
813 | |
---|
814 | ############################################################################### |
---|
815 | # Internal macros |
---|
816 | ############################################################################### |
---|
817 | |
---|
818 | #------------------------------------------------------------------------------ |
---|
819 | def _auto_cleanup '{ |
---|
820 | """ |
---|
821 | Cleanup routine for automatic filter/exposure control |
---|
822 | """ |
---|
823 | |
---|
824 | # drop in filters after finishing, since we do not know where we end up |
---|
825 | # (center of a peak for dscan?) |
---|
826 | AUTO_SET_PILOT = 1 |
---|
827 | AUTO_FILTER_LOCK = 0 |
---|
828 | if(AUTO_LEVEL > 0){ |
---|
829 | filter_trans 1e-10 |
---|
830 | } |
---|
831 | #: remove _auto_cleanup_once from cleanup_once |
---|
832 | cdef("cleanup_once", "", "auto_cleanup_once_key", "delete") |
---|
833 | }' |
---|
834 | |
---|
835 | |
---|
836 | #------------------------------------------------------------------------------ |
---|
837 | def _auto_prescan_head '{ |
---|
838 | """ |
---|
839 | Prepare for automatic filter/exposure control before the start of a scan |
---|
840 | |
---|
841 | This inserts filters with a transmission of 1e-10, sets some values in |
---|
842 | the global variables and adds a cleanup routine to ``cleanup_once``. |
---|
843 | """ |
---|
844 | |
---|
845 | # if automatic filter setting is active start scan with very low |
---|
846 | # filter transmission |
---|
847 | if(AUTO_LEVEL > 0){ |
---|
848 | AUTO_ORIG_EXPTIME = COUNT_TIME |
---|
849 | filter_trans 1e-10 |
---|
850 | if(AUTO_LEVEL > 1){ |
---|
851 | # start with low exposure times |
---|
852 | COUNT_TIME = AUTO_EXP_LOW |
---|
853 | _ctime = COUNT_TIME |
---|
854 | } |
---|
855 | } |
---|
856 | #: add _auto_cleanup to cleanup_once |
---|
857 | cdef("cleanup_once","{_auto_cleanup}; ", "auto_cleanup_once_key",0x20) |
---|
858 | }' |
---|
859 | |
---|
860 | |
---|
861 | #------------------------------------------------------------------------------ |
---|
862 | def _auto_user_chk_counts '{ |
---|
863 | """ |
---|
864 | Check if counts are valid and retake exposure if necessary. |
---|
865 | """ |
---|
866 | |
---|
867 | if(AUTO_LEVEL > 0){ |
---|
868 | # automatic filter and exposure setting (if activated) |
---|
869 | success = _auto_adjust_redo() |
---|
870 | } |
---|
871 | }' |
---|
872 | |
---|
873 | |
---|
874 | #------------------------------------------------------------------------------ |
---|
875 | def _auto_precount '{ |
---|
876 | """ |
---|
877 | Prepare for automatic filter/exposure control at beginning of count command. |
---|
878 | """ |
---|
879 | |
---|
880 | if(AUTO_LEVEL > 0){ |
---|
881 | if(AUTO_MODE == 1 & AUTO_SET_PILOT == 1){ |
---|
882 | # remember the original exposure time |
---|
883 | AUTO_ORIG_EXPTIME = COUNT_TIME |
---|
884 | # set the pilot exposure time |
---|
885 | COUNT_TIME = AUTO_PILOT_EXPTIME |
---|
886 | _ctime = COUNT_TIME |
---|
887 | AUTO_SET_PILOT = 0 |
---|
888 | } |
---|
889 | } |
---|
890 | }' |
---|
891 | |
---|
892 | |
---|
893 | #------------------------------------------------------------------------------ |
---|
894 | def _auto_print_setup '{ |
---|
895 | """ |
---|
896 | Print the configuration options and current values to screen |
---|
897 | |
---|
898 | NOTE: |
---|
899 | The option numbers must be kept in sync between |
---|
900 | :spec:def:`_auto_set_option` and |
---|
901 | :spec:def:`_auto_print_setup`. |
---|
902 | """ |
---|
903 | |
---|
904 | tty_cntl("ho") # home cursor on left upper corner of screen |
---|
905 | tty_cntl("cd") # clear the rest of the screen |
---|
906 | |
---|
907 | tty_cntl("so") # highlight font |
---|
908 | printf("Auto setup:\n") |
---|
909 | tty_cntl("se") # turn off font highlighting |
---|
910 | |
---|
911 | printf("\n 1) %40s: %s", "Auto level {0,1,2}", AUTO_LEVEL) |
---|
912 | if(AUTO_LEVEL == 0) printf(" (no automatic adjustments)") |
---|
913 | if(AUTO_LEVEL == 1) printf(" (automatic filter adjustments)") |
---|
914 | if(AUTO_LEVEL == 2) printf(" (automatic filter and exptime adjustments)") |
---|
915 | printf("\n 2) %40s: %s", "Auto mode {0,1}", AUTO_MODE) |
---|
916 | if(AUTO_MODE == 0) printf(" (post-exposure adjustments)") |
---|
917 | if(AUTO_MODE == 1) printf(" (pilot pre-exposure)") |
---|
918 | printf("\n 3) %40s: %s", "Counter to monitor", AUTO_COUNTER) |
---|
919 | printf("\n 4) %40s: %s", "Count RATE high limit [cts/s]", AUTO_RATE_LIMIT) |
---|
920 | printf("\n 5) %40s: %s", "Target count level [cts]", AUTO_COUNT_TARGET) |
---|
921 | printf("\n 6) %40s: %s", "Count level low limit [cts]", AUTO_COUNT_LOW) |
---|
922 | printf("\n 7) %40s: %s", "Counter saturation (high) limit [cts]", \ |
---|
923 | AUTO_COUNT_HIGH) |
---|
924 | printf("\n 8) %40s: %s", "Transmission step", AUTO_FILTER_FACTOR) |
---|
925 | printf("\n 9) %40s: %s", "Minimum exposure time [s]", AUTO_EXP_LOW) |
---|
926 | printf("\n 10) %40s: %s", "Maximum exposure time [s]", AUTO_EXP_HIGH) |
---|
927 | printf("\n 11) %40s: %s", "Pilot exposure time [s]", AUTO_PILOT_EXPTIME) |
---|
928 | printf("\n 12) %40s: %s", "Count time precision [s]", AUTO_COUNT_PREC) |
---|
929 | printf("\n 13) %40s: %s", "Maximum number of retries", AUTO_RETRY_MAX) |
---|
930 | printf("\n\n") |
---|
931 | }' |
---|
932 | |
---|
933 | |
---|
934 | #------------------------------------------------------------------------------ |
---|
935 | def _auto_set_option '{ |
---|
936 | """ |
---|
937 | Sets a new value for a given option. |
---|
938 | |
---|
939 | DESCRIPTION: |
---|
940 | Sets a new value for a given option from the options menu that was created |
---|
941 | with the :spec:def:`_auto_print_setup` command. |
---|
942 | |
---|
943 | NOTE: |
---|
944 | The option numbers must be kept in sync between |
---|
945 | :spec:def:`_auto_set_option` and |
---|
946 | :spec:def:`_auto_print_setup`. |
---|
947 | |
---|
948 | """ |
---|
949 | |
---|
950 | local _input, _dummy, _valid, _numitems |
---|
951 | |
---|
952 | #---------- |
---|
953 | if ($1==1){ |
---|
954 | auto_set_level |
---|
955 | |
---|
956 | #---------------- |
---|
957 | } else if ($1==2){ |
---|
958 | auto_set_mode |
---|
959 | |
---|
960 | #---------------- |
---|
961 | } else if ($1==3){ |
---|
962 | |
---|
963 | show_counters() |
---|
964 | |
---|
965 | _valid = 0 |
---|
966 | while(!(_valid)){ |
---|
967 | _input = getval("Pleae enter the counter to monitor", AUTO_COUNTER) |
---|
968 | if(cnt_num(_input)<0){ |
---|
969 | printf("ERROR: Invalid counter (%s)\n", _input) |
---|
970 | } else { |
---|
971 | AUTO_COUNTER = cnt_num(_input) |
---|
972 | _valid = 1 |
---|
973 | } |
---|
974 | } |
---|
975 | |
---|
976 | #---------------- |
---|
977 | } else if ($1==4){ |
---|
978 | _valid = 0 |
---|
979 | while(!(_valid)){ |
---|
980 | _input= getval("Upper limit for the counte RATE [cts/sec]", \ |
---|
981 | AUTO_RATE_LIMIT) |
---|
982 | _numitems = sscanf(_input, "%f", _input) |
---|
983 | if(_numitems == 1){ |
---|
984 | if(_input > 0) { |
---|
985 | AUTO_RATE_LIMIT = _input |
---|
986 | _valid = 1 |
---|
987 | } |
---|
988 | } |
---|
989 | if(!(_valid)){ |
---|
990 | printf("ERROR: Invalid input for rate limit (%s)\n", _input) |
---|
991 | } |
---|
992 | } |
---|
993 | |
---|
994 | #---------------- |
---|
995 | } else if ($1==5){ |
---|
996 | _valid = 0 |
---|
997 | while(!(_valid)){ |
---|
998 | _input= getval("Target count level [cts]", AUTO_COUNT_TARGET) |
---|
999 | _numitems = sscanf(_input, "%f", _input) |
---|
1000 | if(_numitems == 1){ |
---|
1001 | if(_input > 0) { |
---|
1002 | AUTO_COUNT_TARGET = _input |
---|
1003 | _valid = 1 |
---|
1004 | } |
---|
1005 | } |
---|
1006 | if(!(_valid)){ |
---|
1007 | printf("ERROR: Invalid target count level (%s)\n", _input) |
---|
1008 | } |
---|
1009 | } |
---|
1010 | |
---|
1011 | #---------------- |
---|
1012 | } else if ($1==6){ |
---|
1013 | _valid = 0 |
---|
1014 | while(!(_valid)){ |
---|
1015 | _input= getval("Count level low limit [cts]", AUTO_COUNT_LOW) |
---|
1016 | _numitems = sscanf(_input, "%f", _input) |
---|
1017 | if(_numitems == 1){ |
---|
1018 | if(_input > 0) { |
---|
1019 | AUTO_COUNT_LOW = _input |
---|
1020 | _valid = 1 |
---|
1021 | } |
---|
1022 | } |
---|
1023 | if(!(_valid)){ |
---|
1024 | printf("ERROR: Invalid count level low limit (%s)\n", _input) |
---|
1025 | } |
---|
1026 | } |
---|
1027 | |
---|
1028 | #---------------- |
---|
1029 | } else if ($1==7){ |
---|
1030 | _valid = 0 |
---|
1031 | while(!(_valid)){ |
---|
1032 | _input= getval("Counter saturation (high) limit [cts]", AUTO_COUNT_HIGH) |
---|
1033 | _numitems = sscanf(_input, "%f", _input) |
---|
1034 | if(_numitems == 1){ |
---|
1035 | if(_input > 0) { |
---|
1036 | AUTO_COUNT_HIGH = _input |
---|
1037 | _valid = 1 |
---|
1038 | } |
---|
1039 | } |
---|
1040 | if(!(_valid)){ |
---|
1041 | printf("ERROR: Invalid counter saturation limit (%s)\n", _input) |
---|
1042 | } |
---|
1043 | } |
---|
1044 | |
---|
1045 | #---------------- |
---|
1046 | } else if ($1==8){ |
---|
1047 | _valid = 0 |
---|
1048 | while(!(_valid)){ |
---|
1049 | _input= getval("Transmission step used to adjust filters", \ |
---|
1050 | AUTO_FILTER_FACTOR) |
---|
1051 | _numitems = sscanf(_input, "%f", _input) |
---|
1052 | if(_numitems == 1){ |
---|
1053 | if(AUTO_FILTER_FACTOR <= 1.2){ |
---|
1054 | printf("Error: Transmission step factor must be >1.2 !\n") |
---|
1055 | printf(" (recommended: 4 - 100, must match available filters)\n") |
---|
1056 | } else if (AUTO_FILTER_FACTOR >= AUTO_RATE_LIMIT){ |
---|
1057 | printf("Error: Transmission step factor must be smaller than\n") |
---|
1058 | printf(" the maximum count rate (%g)\n", AUTO_RATE_LIMIT) |
---|
1059 | } else if (AUTO_FILTER_FACTOR >= AUTO_COUNT_HIGH){ |
---|
1060 | printf("Error: Transmission step factor must be smaller than\n") |
---|
1061 | printf(" the counter saturation limit (%g)\n", AUTO_COUNT_HIGH) |
---|
1062 | } else { |
---|
1063 | AUTO_FILTER_FACTOR = _input |
---|
1064 | _valid = 1 |
---|
1065 | } |
---|
1066 | } |
---|
1067 | if(!(_valid)){ |
---|
1068 | printf("ERROR: Invalid transmission step (%s)\n", _input) |
---|
1069 | } |
---|
1070 | } |
---|
1071 | |
---|
1072 | #---------------- |
---|
1073 | } else if ($1==9){ |
---|
1074 | _valid = 0 |
---|
1075 | while(!(_valid)){ |
---|
1076 | _input= getval("Minimum exposure time [s]", AUTO_EXP_LOW) |
---|
1077 | _numitems = sscanf(_input, "%f", _input) |
---|
1078 | if(_numitems == 1){ |
---|
1079 | if(_input > 0) { |
---|
1080 | AUTO_EXP_LOW = _input |
---|
1081 | _valid = 1 |
---|
1082 | } |
---|
1083 | } |
---|
1084 | if(!(_valid)){ |
---|
1085 | printf("ERROR: Invalid minimum exposure time (%s)\n", _input) |
---|
1086 | } |
---|
1087 | } |
---|
1088 | |
---|
1089 | #----------------- |
---|
1090 | } else if ($1==10){ |
---|
1091 | _valid = 0 |
---|
1092 | while(!(_valid)){ |
---|
1093 | _input= getval("Maximum exposure time [s]", AUTO_EXP_HIGH) |
---|
1094 | _numitems = sscanf(_input, "%f", _input) |
---|
1095 | if(_numitems == 1){ |
---|
1096 | if(_input > 0) { |
---|
1097 | AUTO_EXP_HIGH = _input |
---|
1098 | _valid = 1 |
---|
1099 | } |
---|
1100 | } |
---|
1101 | if(!(_valid)){ |
---|
1102 | printf("ERROR: Invalid maximum exposure time (%s)\n", _input) |
---|
1103 | } |
---|
1104 | } |
---|
1105 | |
---|
1106 | |
---|
1107 | #----------------- |
---|
1108 | } else if ($1==11){ |
---|
1109 | _valid = 0 |
---|
1110 | while(!(_valid)){ |
---|
1111 | _input= getval("Pilot exposure time [s]", AUTO_PILOT_EXPTIME) |
---|
1112 | _numitems = sscanf(_input, "%f", _input) |
---|
1113 | if(_numitems == 1){ |
---|
1114 | if(_input > 0) { |
---|
1115 | AUTO_PILOT_EXPTIME = _input |
---|
1116 | _valid = 1 |
---|
1117 | } |
---|
1118 | } |
---|
1119 | if(!(_valid)){ |
---|
1120 | printf("ERROR: Invalid pilot exposure time (%s)\n", _input) |
---|
1121 | } |
---|
1122 | } |
---|
1123 | |
---|
1124 | #----------------- |
---|
1125 | } else if ($1==12){ |
---|
1126 | local _str |
---|
1127 | |
---|
1128 | _valid = 0 |
---|
1129 | while(!(_valid)){ |
---|
1130 | _str = "Count time rounding precision [s] (e.g.: 0.01; 0=no rounding)" |
---|
1131 | _input= getval(_str, AUTO_COUNT_PREC) |
---|
1132 | _numitems = sscanf(_input, "%f", _input) |
---|
1133 | if(_numitems == 1){ |
---|
1134 | if(_input < 0) { |
---|
1135 | printf("Count time precision must be >=0 \n") |
---|
1136 | } else if(_input > 10){ |
---|
1137 | printf("Count time precision must be smaller than 10 sec\n") |
---|
1138 | } else { |
---|
1139 | AUTO_COUNT_PREC = _input |
---|
1140 | _valid = 1 |
---|
1141 | } |
---|
1142 | } |
---|
1143 | if(!(_valid)){ |
---|
1144 | printf("ERROR: Invalid count time precision (%s)\n", _input) |
---|
1145 | } |
---|
1146 | } |
---|
1147 | |
---|
1148 | #----------------- |
---|
1149 | } else if ($1==13){ |
---|
1150 | _valid = 0 |
---|
1151 | while(!(_valid)){ |
---|
1152 | _input= getval("Maximum number of retries", AUTO_RETRY_MAX) |
---|
1153 | _numitems = sscanf(_input, "%d", _input) |
---|
1154 | if(_numitems == 1){ |
---|
1155 | if(_input > 100) { |
---|
1156 | printf("Maximum number of retries must be < 100 !\n") |
---|
1157 | printf(" (recommended: <30 and >10)\n") |
---|
1158 | } else if(_input <2) { |
---|
1159 | printf("Maximum number of retries must be > 2 !\n") |
---|
1160 | printf(" (recommended: <30 and >10)\n") |
---|
1161 | } else { |
---|
1162 | AUTO_RETRY_MAX = int(_input) |
---|
1163 | _valid = 1 |
---|
1164 | } |
---|
1165 | } |
---|
1166 | if(!(_valid)){ |
---|
1167 | printf("ERROR: Invalid pilot exposure time (%s)\n", _input) |
---|
1168 | } |
---|
1169 | } |
---|
1170 | } |
---|
1171 | }' |
---|
1172 | |
---|
1173 | |
---|
1174 | |
---|
1175 | #------------------------------------------------------------------------------ |
---|
1176 | def _auto_analyze_exposure '{ |
---|
1177 | """ |
---|
1178 | Analyze the previous exposure |
---|
1179 | |
---|
1180 | DESCRIPTION: |
---|
1181 | This macro retrieves the necessary information to analyze the last exposure |
---|
1182 | and to initiate adjustments, if necessary. Usually, this step consists only |
---|
1183 | of retrieving the count value from the monitored SPEC counter, but for more |
---|
1184 | sophisticated experimental setups, this definition could be overwritten to |
---|
1185 | include non-standard procedures, such as retrieving counts from EPICS PVs, |
---|
1186 | etc. |
---|
1187 | |
---|
1188 | USAGE:: |
---|
1189 | |
---|
1190 | > _auto_analyze_exposure |
---|
1191 | |
---|
1192 | """ |
---|
1193 | |
---|
1194 | AUTO_COUNT_RBV = S[AUTO_COUNTER] |
---|
1195 | |
---|
1196 | }' |
---|
1197 | |
---|
1198 | |
---|
1199 | #------------------------------------------------------------------------------ |
---|
1200 | def _auto_adjust() '{ |
---|
1201 | """ |
---|
1202 | Calculate and apply necessary exposure time and filter adjustments. |
---|
1203 | |
---|
1204 | DESCRIPTION: |
---|
1205 | |
---|
1206 | The function returns 1 if transmission or exposure time have been changed, |
---|
1207 | 0 otherwise. |
---|
1208 | |
---|
1209 | USAGE:: |
---|
1210 | > changed = _auto_adjust() |
---|
1211 | |
---|
1212 | """ |
---|
1213 | |
---|
1214 | local _auto_adjusted, _count_time, _factor, _transm, _transm_up, _new_transm |
---|
1215 | |
---|
1216 | # do nothing when auto-level is zero |
---|
1217 | if (AUTO_LEVEL < 1) { |
---|
1218 | return(0) |
---|
1219 | } |
---|
1220 | |
---|
1221 | # set exposure times to default if they are not defined yet |
---|
1222 | if (AUTO_EXP_LOW < 0.0000001) { |
---|
1223 | AUTO_EXP_LOW = 1 |
---|
1224 | } |
---|
1225 | if (AUTO_EXP_HIGH < 0.0000001) { |
---|
1226 | AUTO_EXP_HIGH = 10 |
---|
1227 | } |
---|
1228 | |
---|
1229 | _auto_adjusted = 0 |
---|
1230 | |
---|
1231 | # record last count time |
---|
1232 | _count_time = COUNT_TIME |
---|
1233 | |
---|
1234 | # analyze the exposure in terms of the threshold values |
---|
1235 | _auto_analyze_exposure |
---|
1236 | |
---|
1237 | if(AUTO_DEBUG && 0x1){ |
---|
1238 | printf("\n%s\n", date()) |
---|
1239 | printf("Analyzing exposure with exposure time %f s\n", COUNT_TIME) |
---|
1240 | printf("Obtained count RATE: %f cts/s (saturation limit = %f cts/s)\n",\ |
---|
1241 | AUTO_COUNT_RBV/_count_time, AUTO_RATE_LIMIT) |
---|
1242 | printf("Obtained count level: %f counts\n", AUTO_COUNT_RBV) |
---|
1243 | printf("(Target = %f, Hi limit = %f, low limit = %f\n", \ |
---|
1244 | AUTO_COUNT_TARGET, AUTO_COUNT_HIGH, AUTO_COUNT_LOW) |
---|
1245 | } |
---|
1246 | |
---|
1247 | #----------------------------------------- |
---|
1248 | # 1.) filter adjustments if AUTO_LEVEL > 0 |
---|
1249 | |
---|
1250 | if(AUTO_DEBUG && 0x1){ |
---|
1251 | printf("Filter lock is: %d\n", AUTO_FILTER_LOCK) |
---|
1252 | } |
---|
1253 | |
---|
1254 | # check if filters are already locked (rate has been adjusted) |
---|
1255 | if (!(AUTO_FILTER_LOCK)){ |
---|
1256 | |
---|
1257 | # reduce filter transmission if rate is too high |
---|
1258 | if ( ((AUTO_COUNT_RBV/_count_time) > AUTO_RATE_LIMIT) &\ |
---|
1259 | (filter_get_mask() < filter_max()) ){ |
---|
1260 | |
---|
1261 | if(AUTO_DEBUG && 0x1){ |
---|
1262 | printf("Rate is too high: %f > %f\n", AUTO_COUNT_RBV/_count_time,\ |
---|
1263 | AUTO_RATE_LIMIT) |
---|
1264 | } |
---|
1265 | |
---|
1266 | _new_transm = filter_get_trans()/ AUTO_FILTER_FACTOR |
---|
1267 | filter_trans _new_transm |
---|
1268 | _auto_adjusted = 1 |
---|
1269 | return(_auto_adjusted) |
---|
1270 | } |
---|
1271 | |
---|
1272 | # increase filter transmission if rate is too low |
---|
1273 | if (((AUTO_COUNT_RBV/_count_time) < \ |
---|
1274 | 0.5*AUTO_RATE_LIMIT/AUTO_FILTER_FACTOR) & \ |
---|
1275 | (filter_get_mask() > 0) ){ |
---|
1276 | |
---|
1277 | if(AUTO_DEBUG && 0x1){ |
---|
1278 | printf("Rate is too low: %f < %f\n", AUTO_COUNT_RBV/_count_time, \ |
---|
1279 | 0.5*AUTO_RATE_LIMIT/AUTO_FILTER_FACTOR) |
---|
1280 | } |
---|
1281 | |
---|
1282 | _transm = filter_get_trans() |
---|
1283 | if (AUTO_COUNT_RBV > 0){ |
---|
1284 | _factor = (0.75 * AUTO_RATE_LIMIT) / (AUTO_COUNT_RBV/_count_time) |
---|
1285 | } else { |
---|
1286 | _factor = (0.75 * AUTO_RATE_LIMIT) |
---|
1287 | } |
---|
1288 | # make sure that there is actually a better filter setting available for |
---|
1289 | # the requested new transmission |
---|
1290 | _transm_up = filter_get_trans_up() |
---|
1291 | if(_factor > (_transm_up/_transm)){ |
---|
1292 | _new_transm = _transm * _factor |
---|
1293 | if(_new_transm > 1){ |
---|
1294 | _new_transm = 1 |
---|
1295 | } |
---|
1296 | filter_trans _new_transm |
---|
1297 | _auto_adjusted = 1 |
---|
1298 | return(_auto_adjusted) |
---|
1299 | } else { |
---|
1300 | # there is nothing we can do with the filters |
---|
1301 | AUTO_FILTER_LOCK = 1 |
---|
1302 | if(AUTO_DEBUG && 0x1){ |
---|
1303 | printf("No filter adjustments possible\n") |
---|
1304 | } |
---|
1305 | } |
---|
1306 | } |
---|
1307 | } |
---|
1308 | |
---|
1309 | # avoid counter saturation of the detector if AUTO_LEVEL < 2 or the exposure |
---|
1310 | # time is at AUTO_EXP_LOW |
---|
1311 | if((AUTO_LEVEL) < 2 | (_count_time <= AUTO_EXP_LOW+1e-7)){ |
---|
1312 | if((AUTO_COUNT_RBV > AUTO_COUNT_HIGH) & \ |
---|
1313 | (filter_get_mask() < filter_max())){ |
---|
1314 | |
---|
1315 | if(AUTO_DEBUG && 0x1){ |
---|
1316 | printf("Rate is ok (%f), but counter is saturating (%f > %f)\n",\ |
---|
1317 | AUTO_COUNT_RBV/_count_time, AUTO_COUNT_RBV, AUTO_COUNT_HIGH) |
---|
1318 | } |
---|
1319 | |
---|
1320 | _new_transm = filter_get_trans()/ AUTO_FILTER_FACTOR |
---|
1321 | filter_trans _new_transm |
---|
1322 | AUTO_FILTER_LOCK = 1 |
---|
1323 | _auto_adjusted = 1 |
---|
1324 | return(_auto_adjusted) |
---|
1325 | } |
---|
1326 | } |
---|
1327 | |
---|
1328 | |
---|
1329 | #------------------------------------------------------------------------- |
---|
1330 | # 2.) take real exposure with requested exposure time after pilot exposure |
---|
1331 | # if in pilot mode |
---|
1332 | |
---|
1333 | if(AUTO_LEVEL == 1 && AUTO_MODE == 1){ |
---|
1334 | if(_count_time != AUTO_ORIG_EXPTIME){ |
---|
1335 | if(AUTO_DEBUG && 0x1){ |
---|
1336 | printf("Setting exposure time to %f s\n", AUTO_ORIG_EXPTIME) |
---|
1337 | } |
---|
1338 | |
---|
1339 | # set exposure time to requested exposure time to retake the exposure after |
---|
1340 | # the pilot exposures |
---|
1341 | AUTO_FILTER_LOCK = 1 |
---|
1342 | COUNT_TIME = AUTO_ORIG_EXPTIME |
---|
1343 | _ctime = COUNT_TIME |
---|
1344 | _auto_adjusted = 1 |
---|
1345 | return(_auto_adjusted) |
---|
1346 | } |
---|
1347 | } |
---|
1348 | |
---|
1349 | #----------------------------------------- |
---|
1350 | # 3.) count time scaling if AUTO_LEVEL > 1 |
---|
1351 | |
---|
1352 | if(AUTO_LEVEL > 1){ |
---|
1353 | |
---|
1354 | # calculate exposure time for next exposure |
---|
1355 | if (AUTO_COUNT_RBV > 0){ |
---|
1356 | _factor = AUTO_COUNT_TARGET / AUTO_COUNT_RBV |
---|
1357 | } else { |
---|
1358 | _factor = 1e3 |
---|
1359 | } |
---|
1360 | COUNT_TIME = _auto_calc_exposure(_count_time * _factor) |
---|
1361 | _ctime = COUNT_TIME |
---|
1362 | |
---|
1363 | if(AUTO_DEBUG && 0x1){ |
---|
1364 | printf("Adjusting exposure time from %f to %f sec\n", _count_time, \ |
---|
1365 | COUNT_TIME) |
---|
1366 | } |
---|
1367 | |
---|
1368 | # recount immediately if last exposure time was not within allowed limits |
---|
1369 | if((_count_time < AUTO_EXP_LOW) | (_count_time > AUTO_EXP_HIGH)){ |
---|
1370 | if(AUTO_DEBUG && 0x1){ |
---|
1371 | printf("Previous exposure outside limits: retake immediately\n") |
---|
1372 | } |
---|
1373 | _auto_adjusted = 1 |
---|
1374 | return(_auto_adjusted) |
---|
1375 | } |
---|
1376 | |
---|
1377 | # recount immediately if we are saturated or under-exposed |
---|
1378 | # and count times can still be changed |
---|
1379 | if((AUTO_COUNT_RBV > AUTO_COUNT_HIGH) & \ |
---|
1380 | (_count_time > AUTO_EXP_LOW)){ |
---|
1381 | |
---|
1382 | if(AUTO_DEBUG && 0x1){ |
---|
1383 | printf("Overexposure: retaking exposure immediately\n") |
---|
1384 | } |
---|
1385 | _auto_adjusted = 1 |
---|
1386 | return(_auto_adjusted) |
---|
1387 | } |
---|
1388 | if((AUTO_COUNT_RBV < AUTO_COUNT_LOW) & \ |
---|
1389 | (_count_time < AUTO_EXP_HIGH)){ |
---|
1390 | |
---|
1391 | if(AUTO_DEBUG && 0x1){ |
---|
1392 | printf("Underexposure: retaking exposure immediately\n") |
---|
1393 | } |
---|
1394 | _auto_adjusted = 1 |
---|
1395 | return(_auto_adjusted) |
---|
1396 | } |
---|
1397 | |
---|
1398 | # decrease filter transmission if we are saturated and decreasing the |
---|
1399 | # exposure time is not possible. Recount immediately |
---|
1400 | if((AUTO_COUNT_RBV > AUTO_COUNT_HIGH) & \ |
---|
1401 | (_count_time <= AUTO_EXP_LOW+1e-7) & \ |
---|
1402 | (filter_get_mask() < filter_max())){ |
---|
1403 | |
---|
1404 | if(AUTO_DEBUG && 0x1){ |
---|
1405 | printf("Overexposure but cannot decrease exposure time") |
---|
1406 | printf(" -> reducing filter transmission\n") |
---|
1407 | } |
---|
1408 | |
---|
1409 | _new_transm = filter_get_trans()/ AUTO_FILTER_FACTOR |
---|
1410 | filter_trans _new_transm |
---|
1411 | _auto_adjusted = 1 |
---|
1412 | return(_auto_adjusted) |
---|
1413 | AUTO_FILTER_LOCK = 1 |
---|
1414 | } |
---|
1415 | } |
---|
1416 | |
---|
1417 | return(_auto_adjusted) |
---|
1418 | }' |
---|
1419 | |
---|
1420 | |
---|
1421 | #------------------------------------------------------------------------------ |
---|
1422 | def _auto_check_exposure '{ |
---|
1423 | """ |
---|
1424 | Make sure the user-entered exposure times are consistent |
---|
1425 | |
---|
1426 | USAGE:: |
---|
1427 | |
---|
1428 | > _auto_check_exposure |
---|
1429 | |
---|
1430 | """ |
---|
1431 | |
---|
1432 | if (AUTO_EXP_LOW >= AUTO_EXP_HIGH) { |
---|
1433 | AUTO_EXP_LOW = 1 |
---|
1434 | AUTO_EXP_HIGH = 10 |
---|
1435 | eprint "ERROR: Invalid exposure time values!" |
---|
1436 | printf(" Minimum (%f) must be less than maximum (%f) exposure time\n",\ |
---|
1437 | AUTO_EXP_LOW, AUTO_EXP_HIGH) |
---|
1438 | printf(" Setting exposure times to default values:\n") |
---|
1439 | } |
---|
1440 | }' |
---|
1441 | |
---|
1442 | |
---|
1443 | #------------------------------------------------------------------------------ |
---|
1444 | def _auto_check_levels '{ |
---|
1445 | """ |
---|
1446 | Make sure the user-entered count levels are consistent |
---|
1447 | |
---|
1448 | USAGE:: |
---|
1449 | |
---|
1450 | > _auto_check_levels |
---|
1451 | |
---|
1452 | """ |
---|
1453 | |
---|
1454 | if(AUTO_COUNT_TARGET >= AUTO_COUNT_HIGH){ |
---|
1455 | eprint "ERROR: Invalid count target!" |
---|
1456 | printf("The count target (%f) must be smaller than ", AUTO_COUNT_TARGET) |
---|
1457 | printf("the counter saturation limit (%f).\n", AUTO_COUNT_HIGH) |
---|
1458 | printf("Setting count target to %d counts.\n\n", int(AUTO_COUNT_HIGH/10)) |
---|
1459 | AUTO_COUNT_TARGET = int(AUTO_COUNT_HIGH/10) |
---|
1460 | } |
---|
1461 | if(AUTO_COUNT_LOW >= AUTO_COUNT_TARGET) { |
---|
1462 | eprint "ERROR: Invalid low count limit!" |
---|
1463 | printf("Low count limit (%f) must be smaller than count target (%f).\n", \ |
---|
1464 | AUTO_COUNT_LOW, AUTO_COUNT_TARGET) |
---|
1465 | printf("Setting low count limit to %d counts.\n\n", \ |
---|
1466 | int(AUTO_COUNT_TARGET/10)) |
---|
1467 | AUTO_COUNT_LOW = int(AUTO_COUNT_TARGET/10) |
---|
1468 | } |
---|
1469 | }' |
---|
1470 | |
---|
1471 | |
---|
1472 | #------------------------------------------------------------------------------ |
---|
1473 | def _auto_calc_exposure(t) '{ |
---|
1474 | """ |
---|
1475 | Make sure the requested exposure time is between the min and max values and |
---|
1476 | round it to the given count time precision. |
---|
1477 | |
---|
1478 | USAGE:: |
---|
1479 | |
---|
1480 | > adjusted_time = _auto_calc_exposure(requested_time) |
---|
1481 | |
---|
1482 | """ |
---|
1483 | |
---|
1484 | # round to given precision |
---|
1485 | if (AUTO_COUNT_PREC>1e-7){ |
---|
1486 | t = (int(t/AUTO_COUNT_PREC))*AUTO_COUNT_PREC |
---|
1487 | } |
---|
1488 | |
---|
1489 | # check if we are inside the limits |
---|
1490 | if(t > AUTO_EXP_HIGH){ |
---|
1491 | t = AUTO_EXP_HIGH |
---|
1492 | } else if (t < AUTO_EXP_LOW){ |
---|
1493 | t = AUTO_EXP_LOW |
---|
1494 | } |
---|
1495 | |
---|
1496 | return(t) |
---|
1497 | }' |
---|
1498 | |
---|
1499 | |
---|
1500 | #------------------------------------------------------------------------------ |
---|
1501 | def _auto_adjust_redo() '{ |
---|
1502 | """ |
---|
1503 | Determines whether the auto-adjusting has been successful. |
---|
1504 | |
---|
1505 | DESCRIPTION: |
---|
1506 | |
---|
1507 | If the current exposure does not meet the required criteria, counting |
---|
1508 | is repeated until the best possible filter and exposure settings have been |
---|
1509 | obtained, or a maximum number of retry counts has been reached. |
---|
1510 | The function returns 1 in case of success, 0 otherwise. |
---|
1511 | |
---|
1512 | USAGE:: |
---|
1513 | |
---|
1514 | > success = _auto_adjust_redo() |
---|
1515 | |
---|
1516 | NOTE: |
---|
1517 | This macro makes use of the :spec:def:`recount` macro, which has to be |
---|
1518 | added to SPEC during the startup procedure. |
---|
1519 | |
---|
1520 | """ |
---|
1521 | |
---|
1522 | local retryCount |
---|
1523 | local redo |
---|
1524 | local _success |
---|
1525 | |
---|
1526 | _success = 1 |
---|
1527 | AUTO_SET_PILOT = 0 |
---|
1528 | |
---|
1529 | if (AUTO_LEVEL < 1) { |
---|
1530 | return(_success) |
---|
1531 | } else { |
---|
1532 | retryCount = 0 |
---|
1533 | redo = 1 |
---|
1534 | while (redo != 0) { |
---|
1535 | redo = 0 |
---|
1536 | retryCount++ |
---|
1537 | if (_auto_adjust() != 0) { |
---|
1538 | if (retryCount < AUTO_RETRY_MAX) { |
---|
1539 | redo = 1 |
---|
1540 | } else { |
---|
1541 | eprint " >> Couldn\'t optimize filter and exposure settings. <<" |
---|
1542 | } |
---|
1543 | } |
---|
1544 | if (redo != 0) { |
---|
1545 | # repeat exposure |
---|
1546 | recount COUNT_TIME |
---|
1547 | } else { |
---|
1548 | _success = 1 |
---|
1549 | redo = 0 |
---|
1550 | } |
---|
1551 | } |
---|
1552 | AUTO_SET_PILOT = 1 |
---|
1553 | AUTO_FILTER_LOCK = 0 |
---|
1554 | return (_success) |
---|
1555 | } |
---|
1556 | }' |
---|
1557 | |
---|
1558 | #------------------------------------------------------------------------------ |
---|
1559 | # define this only if there is no _clear_screen function available yet |
---|
1560 | if (!(whatis("_clear_screen") & 0x2)){ |
---|
1561 | def _clear_screen '{ |
---|
1562 | """ |
---|
1563 | Clears the terminal screen |
---|
1564 | |
---|
1565 | DESCRIPTION: |
---|
1566 | Clears the screen without losing the screen history or messing up the |
---|
1567 | scrolling capabilities (this has been a problem for certain terminals) |
---|
1568 | by blanking out the entire height of the screen with newlines and |
---|
1569 | returning the cursor to the top left corner. |
---|
1570 | |
---|
1571 | USAGE:: |
---|
1572 | |
---|
1573 | > _clear_screen |
---|
1574 | |
---|
1575 | """ |
---|
1576 | |
---|
1577 | # update the ROWS and COLS variables in case the terminal has been resized |
---|
1578 | tty_cntl("resized?") |
---|
1579 | |
---|
1580 | # print as many newlines as there are ROWS in terminal |
---|
1581 | cl_text = "" |
---|
1582 | for (i=0;i<ROWS;i++){ |
---|
1583 | cl_text = cl_text "\n" |
---|
1584 | } |
---|
1585 | printf(cl_text) |
---|
1586 | |
---|
1587 | # move back to the top of the screen and clear to end of the screen |
---|
1588 | tty_move(0,0) |
---|
1589 | tty_cntl("cd") |
---|
1590 | |
---|
1591 | }' |
---|
1592 | } |
---|
1593 | |
---|
1594 | ############################################################################### |
---|
1595 | # End of $Id: $ |
---|
1596 | ############################################################################### |
---|