source: fact/tools/PyDimCtrl/ScriptsForPyDimCtrl.py@ 14530

Last change on this file since 14530 was 14466, checked in by neise, 12 years ago
further evolving
File size: 32.2 KB
Line 
1#!/usr/bin/python -tti
2
3import time
4from factdimserver import *
5import numpy as np
6import types
7import sys
8
9last_drive_kwargs = {}
10last_drive_method = None
11
12bias_calibration = {}
13
14report_length = 0
15
16source_list = [
17 ['Crab', 0.6, 50, -130],
18 ["1ES 2344+51.4", 0.6, 90, -90 ],
19 ["Mrk 501", 0.6, -22, -22+180 ],
20 ["Mrk 421", 0.6, 90, -90 ],
21 ["1ES 1218+304", 0.6, -5, -5+180 ],
22 ["1ES 1959+650", 0.6, 155, 155-180 ],
23 ["Dark Patch 2", 0.6, 90, -90 ],
24 ["Dark Patch 3", 0.6, 90, -90 ],
25 ["H 1426+428", 0.6, 90, -90 ],
26 ["IC 310", 0.6, -18, -18+180 ],
27 ["PKS 2155-304", 0.6, 90, -90 ] ]
28
29sourcedict = {}
30def make_sourcedict():
31 for s in source_list:
32 sourcedict[s[0]] = {}
33 sourcedict[s[0]]['wobble_offset'] = s[1]
34 sourcedict[s[0]]['wobble_angle1'] = s[2]
35 sourcedict[s[0]]['wobble_angle2'] = s[3]
36
37
38
39
40
41def wait_nice(self, state_num, timeout=None):
42 global report_length
43 if not hasattr(self, 'stn'):
44 raise TypeError(self.name+' has no CMD called STATE')
45 if timeout == None:
46 timeout = float('inf')
47 else:
48 timeout = float(timeout)
49 start = time.time()
50 intermed = time.time()-1.
51 while not self.stn == state_num:
52 time.sleep(0.1)
53 if time.time() - intermed >= 1.:
54 report = str(fad_control.events()[0]) + ' events @ ' + str( ftm_control.trigger_rates()[3]) + ' Hz'
55
56 sys.stdout.write('\r'+' '*report_length)
57 sys.stdout.flush()
58 sys.stdout.write('\r'+report)
59 sys.stdout.flush()
60 report_length = len(report)
61
62 intermed = time.time()
63
64 if time.time() >= start+timeout:
65 report_length=0
66 print
67 return False
68 report_length=0
69 print
70 return True
71
72fad_control.wait_nice = types.MethodType( wait_nice, fad_control)
73
74
75def FadConnectCrate( crate ):
76 cratenum = None
77
78 if crate == 'all':
79 print "connecting to all crates"
80 for i in range( 40 ):
81 time.sleep(3.8)
82 fad_control.connect(i)
83 print "... done"
84 else:
85 try:
86 cratenum = int(crate)
87 except ValueError as e:
88 print "cannot convert crate parameter to integer. crate=", crate
89 print e
90 raise
91
92 if cratenum != None:
93 print "connecting to crate", cratenum
94 for i in range(cratenum*10, (cratenum+1)*10 ):
95 time.sleep(3.8)
96 fad_control.connect(i)
97 print "... done"
98
99
100def FadDisconnectCrate( crate ):
101 cratenum = None
102
103 if crate == 'all':
104 print "connecting to all crates"
105 for i in range( 40 ):
106 fad_control.disconnect(i)
107 print "... done"
108 else:
109 try:
110 cratenum = int(crate)
111 except ValueError as e:
112 print "cannot convert crate parameter to integer. crate=", crate
113 print e
114 raise
115
116 if cratenum != None:
117 print "connecting to crate", cratenum
118 for i in range(cratenum*10, (cratenum+1)*10 ):
119 print 'disconnecting from i', time.time()
120 fad_control.disconnect(i)
121 print "... done"
122
123
124
125def IsReadyForDataTaking( verbose=False ):
126 """ Checking the system statuses if they are ready for data taking
127 """
128 if verbose:
129 print "--------------------------------------"
130 print "Checking the system statuses of:"
131 print "FEEDBACK, BIAS, FAD and DRIVE_CONTROL"
132 print "--------------------------------------"
133
134 print "...waiting for FEEDBACK"
135 print " to be in state 12: CurrentControl"
136 feedback.wait(12)
137
138 if verbose:
139 print "...waiting for BIAS_CONTROL"
140 print " to be in state 9: VoltageOn"
141 bias_control.wait(9)
142
143 if verbose:
144 print "...waiting for FAD_CONTROL"
145 print " to be in state 4: Connected"
146 fad_control.wait(4)
147
148 if verbose:
149 print "...waiting for drive_CONTROL"
150 print " to be in state 8: Tracking"
151 drive_control.wait(8)
152
153 if verbose:
154 print "...system statuses OK"
155 print "--------------------------------------"
156
157def NotReadyForDataTaking( servers_n_targets = [ (feedback, 12),
158 (bias_control, 9),
159 (fad_control, 4) ] ):
160 """ Checking the system statuses if they are ready for data taking
161 return list of servers, which are NOT ready for Data Taking
162 so one can use this function like this
163 if not NotReadyForDataTaking():
164 # freak out
165 else:
166 # start data taking
167 """
168 not_ready = []
169
170 print "--------------------------------------"
171 print "Checking the system statuses of:"
172 for server,target in servers_n_targets:
173 print server.__name__ , ','
174 print
175 print "--------------------------------------"
176
177 for n, server, target in enumerate(servers_n_targets):
178 if server.stn != target:
179 print server.__name__, "NOT in state ", target
180 not_ready.apppend((server,target))
181
182 return not_ready
183
184
185
186
187def PrepareBiasForDataTaking():
188 """ should have the original behaviour, no new fancy features
189 check feedback state before switching BIAS ON and ramping up to nominal Voltage
190 """
191
192 start = time.time()
193 while (feedback.stn != 12):
194 time.sleep(0.1)
195 if time.time() > start + 10.:
196 print "==================================================="
197 print " feedback is not in state 'CurrentControl' "
198 print " OPERATOR: "
199 print " goto feedback console and check the state of "
200 print " feedback by typing [st] to find out what the"
201 print " current state means and maybe needs to be done"
202 print " this script will wait for state 'CurrentControl'"
203 print "==================================================="
204 feedback.wait(12)
205
206 bias_control.set_global_dac(1)
207
208 start = time.time()
209 while (bias_control.stn != 9):
210 time.sleep(0.1)
211 if time.time() > start + 10.:
212 print '==================================================='
213 print ' switching on bias not successfull'
214 print ' biasctrl is not in state "VoltageOn"'
215 print ''
216 print ' OPERATOR:'
217 print ' goto biasctrl console and check the state of'
218 print ' biasctrl by typing [st] to find out what the'
219 print ' current state means and maybe needs to be done'
220 print ''
221 print ' this script will wait for state "VoltageOn"'
222 print '==================================================='
223 bias_control.wait(9)
224
225 bias_control.wait(5)
226 bias_control.wait(9)
227
228 print "bias is on, and feedback-program is working, but we wait 45sec for the current readings..."
229 time.sleep(45)
230 print "...done"
231
232
233def StopTracking():
234 """ should have the original behaviour, no new fancy features
235 stop drivectrl tracking the current source
236 """
237 drive_control.stop()
238 drive_control.wait(6) #Armed
239
240 print "Drive Armed"
241 print "Tracking Stopped"
242
243
244def SwitchOnBias():
245 """ should have the original behaviour, no new fancy features
246 bring Feedback to state CurrentControIdle and switch on Bias
247 """
248 print ' switching on current controll feedback'
249 feedback.stop()
250 print ' ... starting current control feedback '
251 feedback.start_current_control(0.)
252 feedback.enable_output(1) # 1 means True here ... this needs improvement.
253
254 print ' ...waiting for FEEDBACK to be in state 9: CurrentCtrlIdle'
255 feedback.wait(9)
256 print '... feedback is running.'
257
258 print ' switching bias on by, setting DAC to 1 globally'
259 bias_control.set_global_dac(1)
260
261 print ' ...waiting for BIAS to be in state 9: VoltageOn'
262 bias_control.wait(9)
263 print ' ...1 DAC globally set'
264
265
266 print ' ...waiting for BIAS to be in state 5: Ramping'
267 bias_control.wait(5)
268 print ' ...ramping to nominal voltage'
269
270 print ' ...waiting for BIAS to be in state 9: VoltageOn'
271 bias_control.wait(9)
272 print ' ...bias on'
273
274 print ' waiting 45sec for the current control to stabilize...'
275 time.sleep(45.)
276 print ' ... done, bias on'
277
278
279 # the feedback should be in state 'CurrentCtrlIdle'(9) now since 30.05.12
280 # if feedback.stn != 9:
281 # print "feedback is in state:", feedback.sts , "(", feedback.stn, ")"
282 # print "but is should be in state CurrentCtrlIdle (9)"
283 # print "aborting"
284 # return
285
286
287
288def WaitForTracking( verbose = False):
289 """ Wait for drivectrl to reply that its tracking the given source
290 """
291 if verbose:
292 print "...waiting for DRIVE_CONTROL"
293 print " to be in state 7: Moving"
294 drive_control.wait(7)
295 if verbose:
296 print "...moving"
297
298 if verbose:
299 print "...waiting for DRIVE_CONTROL"
300 print " to be in state 8: Tracking"
301 drive_control.wait(8)
302 if verbose:
303 print "...tracking requested wobble position"
304
305 if verbose:
306 print "waiting 10 sec for drive to calm down"
307 print "and tracking beeing stable"
308 time.sleep(10)
309
310
311
312def Take( time, num_events, runtype, verbose=False):
313 """ more general version of e.g. TakePedestalOnRun
314 Note: One has to check, if Ready for *Take* by oneself
315 """
316 runtype += '\0'
317
318 if verbose:
319 print ' taking', runtype,'. ', num_events, 'events in', time, 'seconds'
320 mcp.start(time, num_events, runtype)
321
322 if verbose:
323 print '...waiting for FAD to be in state 8: Writing Data'
324 fad_control.wait(8) # Writing Data
325 if verbose:
326 print '...waiting for FAD to be in state 4: Connected'
327 fad_control.wait_nice(4) # Connected
328 if verbose:
329 print '... done'
330
331def TakeBetter( time, num_events, runtype,
332 Bias = None,
333 Drive = None,
334
335 verbose=False):
336 """
337 """
338 if Bias not in [None, 'On', 'Off']:
339 raise ValueError('Bias needs to be one of [None, 'On', 'Off']')
340 return False
341
342
343 runtype += '\0'
344
345 # FAD:
346 #
347 # It makes no sense to try to take data, when the FADs are not well connected.
348 # Also I think it makes no sense to start datataking, when FAD is in WritingData
349 # and when MCP is not in an Idle state...
350 #
351 # we will check if FAD is in Connected(4), if in Writing_Data(8), we will send: close_all_open_files()
352 # if in one of the configuring states(5,6,7) we will send reset_configure
353 # if in Connecting(3), we will try to find which board is making problems...
354 # and disconnect and connect it --> THREE TIMES
355 # if it doesn't help.
356 # we abort.
357 #
358 #
359
360
361 # FTM:
362 # the ftm is not so critcal, since it makes no problems normally...
363 # It can be in triggerON(4) or Idle(3)
364 # Connected(2) is not good here we need a power cycle
365 # Any of the Configured States (5,6,7) should be treated with reset_configure()
366 #
367 # we will anyway check if in Connected(2) before starting.
368
369 # DRIVE_CONTROL:
370 # in case *Drive* is a valid sourcename from sourcedict,
371 # we will give the command to point to that source in ON mode
372 # in case *Drive* is a tuple of ('sourcename', 1 || 2)
373 # We will point to that soource in wobble mode.
374 #
375 # If Drive is 'Stop. The Drive will be stopped
376 #
377 # In anycase The Drive will be checked for not beeing in the state ERROR
378 # in that case we will send DRIVE_CONTROL/STOP and the last tracking
379 # command or nothing in case Drive = 'Stop'
380 #
381 # In case Drive is None no commands will be send to DRIVE_CONTROL at allow
382
383 # RATE_CTRL
384 #
385 # Rate_control should be in Connected(4) and not lower
386 # 5,6,7 should not be the case ... STOP will help, I hope
387 #
388 # we will try to get it into Connected, by sending STOP once
389 # if not successful we abort
390
391 start_time = time.time()
392 duration = 10.
393 while fad_control.stn != 4:
394 if fad_control.stn in [5,6,7]: # Configure State --> Reset_Configure
395 fad_control.reset_configure()
396 elif fad_control.stn == 8: #WritingData --> Close_all_open_files()
397 fad_control.close_open_files()
398 elif fad_control.stn == 3: #Connecting --> try to find 'bad' board and reconnect
399 duration = 60.
400 print 'fad_control in state Connecting ... trying to find "bad" board'
401 print 'timeout increased to 60.sec'
402 conn = GetFadConnections()
403 bad = np.where( conn != 0x42 )[0]
404 print 'possible bad boards', bad
405 print 'disconnecting'
406 for b in bad:
407 fad_control.disconnect(b)
408 time.sleep(3.)
409 for b in bad:
410 fad_control.connect(b)
411 else: # really bad .. abort
412 print 'ERROR: FAD_CTRL in state', fad_control.stn, fad_control.sts
413 print 'I do not know how to treat that ... aborting'
414 return False
415
416 time.sleep(1.)
417 if time.time() - start_time > duration:
418 print 'Timeout during try to get FAD into Connected'
419 return False
420
421 # BIAS
422 #
423 # As well it makes no sense to try to take data, when the Bias control is in an
424 # undefined state.
425 # When *Bias* is 'On' we will take care that the Bias voltage is on, and stays on
426 # When *Bias* is 'Off' we will shut bias down and do nothing more
427 # When *Bias* is None -default- then no commands will be send to BiasCtrl
428
429 start_time = time.time()
430 duration = 20.
431 if Bias == 'On':
432 if (bias_control.voltage()[0:320].mean() > 60) and
433 ( (bias_control.stn == 5) or (bias_control.stn == 9) )
434
435 elif Bias == 'Off':
436
437
438 if verbose:
439 print ' taking', runtype,'. ', num_events, 'events in', time, 'seconds'
440 mcp.start(time, num_events, runtype)
441
442 if verbose:
443 print '...waiting for FAD to be in state 8: Writing Data'
444 fad_control.wait(8) # Writing Data
445 if verbose:
446 print '...waiting for FAD to be in state 4: Connected'
447 fad_control.wait_nice(4) # Connected
448 if verbose:
449 print '... done'
450
451
452
453def TakeData():
454 """ taking a Data Set (1x Pedestal On, 1x LPext, 4x5min DataRun)
455 """
456 # take a Pedestal run
457 IsReadyForDataTaking()
458 print 'taking External Light Pulser with BIAS on 1000 ...'
459 Take(-1, 1000, 'pedestal')
460
461 # take a ExtLP run
462 IsReadyForDataTaking()
463 print 'taking External Light Pulser with BIAS on 1000 ...'
464 Take(-1, 1000, 'light-pulser-ext')
465
466 #Data Taking with Full Trigger Area (4x5min)
467 for run in range(4):
468 print 'taking data run', run+1, 'out of 4'
469 IsReadyForDataTaking()
470 Take( 300, -1, 'data')
471
472def TakeDrsCalibration():
473 """ script for DRS-Calibration before Data taking
474 """
475 print 'script for DRS-Calibration before Data taking'
476 print 'starting up...'
477
478 feedback.enable_output(1)
479 # Making sure bias is off, before the DRS calibration starts
480 bias_control.set_zero_voltage()
481 print '...ramping Voltage down'
482 print ' ...waiting for BIAS to be in state 7: Voltage Off'
483 bias_control.wait(7) #VoltageOff
484 print '...BIAS voltage is switched off'
485
486 # starting the DRS calibration
487 fad_control.start_drs_calibration()
488
489 # taking first DRS:Pedestal with 1000 Events and ROI 1024
490 print 'taking DRS:Pedestal 1000 ...'
491 fad_control.wait(4) #Connected
492 Take(-1, 1000, 'drs-pedestal')
493
494 # taking DRS:Gain with 1000 Events and ROI 1024
495 print ' taking DRS:Gain 1000 ...'
496 fad_control.wait(4) #Connected
497 Take(-1, 1000, 'drs-gain')
498
499 # taking DRS:Pedestal 1000 Events and ROI 1024
500 print 'taking DRS:Pedestal 1000 ...'
501 fad_control.wait(4) #Connected
502 Take(-1, 1000, 'drs-pedestal')
503
504 print ' ... done'
505
506 # taking again a DRS:Pedestal with 1000 Events and ROI 1024 for a crosscheck of calculated calibrations constants
507 print ' taking crosscheck DRS:Pedestal 1000 ...'
508 fad_control.set_file_format(2)
509 fad_control.wait(4) #Connected
510 Take(-1, 1000, 'drs-pedestal')
511
512
513 # taking DRS:Time with 1000 Events and ROI 1024
514 print ' taking DRS:Time 1000 ...'
515 fad_control.wait(4) #Connected
516 Take(-1, 1000, 'drs-time')
517
518
519 # taking DRS:Time upshifted 1000 Events and ROI 1024
520 print 'taking DRS:Time upshifted 1000 ...'
521 fad_control.wait(4) #Connected
522 Take(-1, 1000, 'drs-time-upshifted')
523
524 # taking a Pedestal with 1000 Events and ROI 300 for secondary baseline...
525 print 'taking Pedestal 1000 for secondary baseline... with ROI=300'
526 fad_control.reset_secondary_drs_baseline()
527 fad_control.wait(4) #Connected
528 Take(-1, 1000, 'pedestal')
529
530 # taking crosscheck Pedestal 1000 Events and ROI 300
531 print ' taking crosscheck Pedestal 1000 ...with ROI=300'
532 fad_control.set_file_format(2)
533 fad_control.wait(4) #Connected
534 Take(-1, 1000, 'pedestal')
535
536 print '----------------------------------------------------'
537 print 'This is the end of the'
538 print 'DRS-Calibration before Data taking'
539 print '----------------------------------------------------'
540
541
542def FirstDrsCalib( SkipCurrentCalib=False ):
543 """ performs the everything, which is done in the FirstDrsCalib Script as well .
544 """
545 # As a First step we want to calibrate the current, which are read from the bias crate,
546 # and not take a DRS calibration, as it is mentioned in the data taking page...
547 # so for this we should get the feedback and biasctrl programs into known states
548 # I think it is good to try a RECONNECT to the bias, and make sure the voltage is off
549 # Since we do not know, what the feedback program is doing at the moment, we should as well,
550 # tell it to keep its mouth shut ... just to be sure, we know whats going on
551 print "stopping feedback"
552 feedback.stop()
553
554 time.sleep(2)
555 # stopping should always be possible, and end in state 'Connected'(6)
556 print " ...waiting for FEEDBACK to be in state 6: Connected"
557 feedback.wait(6)
558 print "..done"
559
560 #BIAS_CONTROL/RECONNECT
561 # If we were disconnected, and this was the first try of the night, the bias_ctrl should
562 # be in state 'VoltageOff'(7) more or less immediately
563 #.s BIAS_CONTROL 3
564 #.s BIAS_CONTROL 7 5000
565 # if these assumptions are all wrong, then we might have been properly connected anyway,
566 # and just have to ramp down... lets do it, but wait forever, in case it does not work
567 print " switching off bias"
568 bias_control.set_zero_voltage()
569 time.sleep(2)
570 print " ...waiting for BIAS to be in state 7: VoltageOff"
571 bias_control.wait(7)
572 print " ...done"
573
574 if not SkipCurrentCalib:
575 # in case we reach this line, the voltages are all off, and the feedback does not do anything
576 # So lets do the current calibration, therefor we tell the bias crate to ramp up just 1 single DAC count(~22mV)
577 # the result of this action is, to get bias_ctrl into the state 'VoltageOn'(9), but since we only go one DAC count it shouldn't take long
578 print " setting bias globally to 1 DAC"
579 bias_control.set_global_dac(1)
580
581 time.sleep(2)
582 print " ...waiting for BIAS to be in state 9: VoltageOn"
583 bias_control.wait(9)
584 print " ...done"
585
586 # now we may tell the feedback program to calibrate the currents ...
587 # I do not understand, if I have to explicitely allow the feedback program to generate output,
588 # or if it just produces output...
589 # As far as I understand, the feedback output enable status is the same,
590 # as it was before I send the STOP command... so it is unknown at this point.
591 # and in addition enabling or disabling the output, when STOPed is not possible as far as I know...
592 # I try to enable it anyway.
593 print " enabling output for feedback"
594 feedback.enable_output(1)
595 time.sleep(2)
596 print " ...done"
597
598 print " calibrating bias crate current readings..."
599 feedback.calibrate_currents()
600 time.sleep(5)
601 # in order to find out when the calibration ends, we have to wait for the transistion from state
602 # 'Calibrating'(13) back to 'Connected'(6)
603 print " ...waiting for FEEDBACK to be in state 13: Calibrating"
604 feedback.wait(13)
605 print " ...waiting for FEEDBACK to be in state 6: Connected"
606 feedback.wait(6)
607
608 # Thomas Bretz told me, that the feedback, after this is step has disabled its output
609 # and is in the mode, we might call 'temperature control' even there is no temerature beeing controlled.
610 # I don't know where the voltage is ... in order to perform the calibration, the feedback had to
611 # ramp up to 2V below the operational voltage, i.e. about 1V below the breakdown voltage
612
613 # We want to take a DRS amplitude calibration so we have to ramp down the bias voltage.
614 # this 10sec wait is needed in order for the bias not to disconect all the time...
615 print " ... current calibration done"
616 #time.sleep(10)
617
618 print " switching off bias"
619 bias_control.set_zero_voltage()
620 #time.sleep(5)
621 print " ...waiting for BIAS to be in state 7: VoltageOff"
622 bias_control.wait(7)
623 print " ...done"
624
625 # So now we can take the 3 runs, which are called DRS amplitude calibration:
626 # A pedestal run with ROI=1024
627 # A gain calibration run with ROI=1024
628 # and a second pedestal run, with the same ROI as our next data will be, i.e. ROI=300 in this case
629 print "taking DRS:Pedestal 1000 ..."
630 print "==================================================="
631 print "OPERATOR: "
632 print "observe Events tab and make sure there are no patches "
633 print "with strange behaviour, which can be caused "
634 print "by DRS-CHIP Problems"
635 print "==================================================="
636
637 fad_control.start_drs_calibration()
638 #time.sleep(0.5)
639 Take( -1, 1000, 'drs-pedestal')
640
641 print "taking DRS:Gain 1000 ..."
642 Take( -1, 1000, 'drs-gain')
643
644 time.sleep(2)
645 if GetDrsCalibGainRms():
646 print
647 print 'First DRS Calib Script will be aborted'
648 print 'operator, please power cycle FACT'
649 return False
650
651 print "taking Pedestal 1000 ..."
652 Take( -1, 1000, 'pedestal')
653
654 # okay this is the DRS calibration for the next few runs.
655 # we are now asked to take again a pedestal run, which can be used, to
656 # calculate the electronics noise for instance ... since the shutter is closed and the
657 # voltage is off .. there should not be alot of signal in it :-)
658 print "taking crosscheck Pedestal 1000 ..."
659 fad_control.set_file_format(2)
660 Take(-1, 1000, 'pedestal')
661
662 # now we want to take a run, with dark counts events
663 # so we need to ramp up the voltage
664 # we want to use the 'current control' more so we give the commands for this...
665 print "switching on current controll feedback ..."
666 feedback.stop()
667 feedback.start_current_control(0.0)
668 feedback.enable_output(1)
669 # the feedback should be in state 'CurrentControl'(12) now
670 # the feedback should be in state 'CurrentCtrlIdle'(9) now since 30.05.12
671 print "...waiting for FEEDBACK to be in state 9: CurrentCtrlIdle"
672 feedback.wait(9)
673 print "... done"
674 print "switching on bias"
675 # now we give the feedback a hint, that it may ramp ...
676 bias_control.set_global_dac(1)
677 # after this command the bias_ctrl should be in state 'VoltageOn'(9) after a second or so
678 print "...waiting for BIAS to be in state 9: VoltageOn"
679 bias_control.wait(9)
680 print "...1 DAC globally set"
681 # then usually it takes some time until the feedback has enough information to really start controlling the voltage
682 # when the feedback actually kicks in, the bias is first in state 'Ramping'(5) for some seconds and finally in 'VoltageOn'(9)
683 # again
684 print "...waiting for BIAS to be in state 5: Ramping"
685 bias_control.wait(5)
686 print "...ramping to nominal voltage"
687 print "...waiting for BIAS to be in state 9: VoltageOn"
688 bias_control.wait(9)
689 print "...bias on"
690 # here we should wait 45 sec in order for the current control to get enough current readings and temp readings to stabilize..
691 print "waiting 45sec for the current control to stabilize..."
692 time.sleep(45)
693 print "... done"
694
695 # so now we can take the dark count run ...
696 # this might be changed in the future ... either the number of events or the the ROI might be changed
697 # then the DRS calibration above, and the pedestal run in between have to be changed as well.
698 print "taking Pedestal with BIAS on 3000 ..."
699 Take(-1, 3000, 'pedestal')
700
701 # at the end the bias voltage should be ramped down, since in a few seconds a shifter wit ha flashlight
702 # will come out to open the shutter...
703 print "switching OFF bias ..."
704 bias_control.set_zero_voltage()
705 print "...waiting for BIAS to be in state 7: VoltageOff"
706 bias_control.wait(7)
707 print "...done"
708 print "This is the end of First DRS Calibration"
709 print "----------------------------------------------------"
710 print ">"
711
712def Ratescan( ra=None, dec=None, sourcename=None):
713 """
714# call it by: .x ScriptsForDimCtrl/Ratescan.dim mode=<trackmode> ra=<Right ascension> dec=<Declination> source=<source_name>
715# mode=0: Manual tracking Mode: set tracking in drivectrl manually
716# mode=1: Coordinate Mode: scripts sends tracking command to drivectrl with the given RaDec coordinates
717# mode=2: source Mode: scripts sends tracking command to drivectrl with the given source_name
718
719 """
720 print '======================================'
721 print 'RATESCAN'
722 print '======================================'
723 print 'Preparing Drive'
724
725
726 if None == ra and None == dec and None == sourcename:
727 print 'Manual tracking Mode'
728 print '---------------------'
729 print 'OPERATOR'
730 print 'change tracking in drivectrl manually'
731 print 'script will wait for drive'
732 print 'to be in state tracking'
733 elif None != ra or None != dec:
734 try:
735 ra = float(ra)
736 dec = float(dec)
737 except TypeError:
738 raise
739
740 print '...stop tracking'
741 StopTracking()
742 print '...change tracking of telescope to:'
743 print '...Ra = ', ra
744 print '...Dec = ', dec
745 drive_control.track( ra, dec)
746 elif None != sourcename:
747 print '...stop tracking'
748 StopTracking()
749 print '...change tracking of telescope to:', sourcename
750 sourcename += '\0'
751 drive_control.track_source( 0, 0, sourcename)
752 else:
753 print 'type(ra)', type(ra), '\tra', ra
754 print 'type(dec)', type(dec), '\tdec', dec
755 print 'type(sourcename)', type(sourcename), '\tsourcename', sourcename
756 raise ValueError('RateScan does not know what to do with its parameters. Bug!')
757 return False
758
759 IsReadyForDataTaking()
760
761 print 'Starting Ratescan'
762 print '...waiting for Ratescan'
763 print ' to be in state 4: Connected'
764
765
766 if not rate_scan.wait(4, timeout=5.): #Connected
767 # we went into timeout!
768 print 'Rate_Scan not in correct state'
769 print 'OPERATOR:'
770 print '+ check connection to ftm control'
771 print 'we went into to 5sec. timeout while waiting for RATE_SCAN to be in state Connected'
772 print 'aborting'
773 return False
774
775 rate_scan.start_threshold_scan( 50, 1000, -10)
776 if not rate_scan.wait( 6, timeout=10.): # Statename???
777 # we went into timeout
778 print 'ratescan not started'
779 print 'we went into 10sec. timeout while waiting for RATE_SCAN to start the Scan'
780 print 'aborting'
781 return False
782
783 print '...processing ratescan'
784 if not rate_scan.wait( 4, timeout=2700.): # Connected
785 # we went into timeout
786 print 'we went into 2700sec. timeout while waiting for RATE_SCAN to finish'
787 print 'aborting'
788 return False
789
790 print 'Ratescan finished successfully'
791 return True
792
793
794def ResetCrate( crate_num ):
795 """ Reset Crate
796 crate_num = 0,1,2 or 3 the number of the crate to reset.
797 crate_num = 'all' is NOT YET SUPPORTED
798 """
799 c = int(crate_num)
800
801 print '======================================'
802 print 'Crate-Reset for crate ', c
803 print '======================================'
804
805 print '...resetting MCP'
806 mcp.reset()
807 time.sleep(5.)
808 print '...diconnecting FAD boards of crate ', c
809 FadDisconnectCrate( c )
810 time.sleep(2.)
811
812 print '...disconnecting All FTUs'
813 ftm_control.enable_ftu( -1, 0) # -1 for all, and 0 for False
814 time.sleep(2.)
815
816 print '...checking state of FTM_Control'
817 print '...waiting for state 3: Idle'
818 if not ftm_control.wait(3, 2.): # Idle
819 print '...stopping trigger'
820 ftm_control.stop_trigger()
821 ftm_control.wait(3) # wait for Idle endlessly
822
823 print '...resetting crate'
824 ftm_control.reset_crate( c )
825 time.sleep(2.)
826
827 print '...connecting All FTUs'
828 ftm_control.enable_ftu( -1, 1) # -1 for all, and 1 for yes, or True
829 time.sleep(4.)
830
831 print '...pinging FTUs'
832 ftm_control.ping()
833
834 print '...connecting FAD boards of crate', c
835 FadConnectCrate(c)
836 print '======================================'
837 print 'Crate-Reset for crate', c, 'finished'
838 print '======================================'
839
840def GetDrsCalibGainRms():
841#drs_calibration(self) method of factdimserver.FAD_CONTROL instance
842#DESC in SERVICE_DESC is empty ?!
843#I:1;I:3;F:1474560;F:1474560;F:1474560;F:1474560;F:1474560;F:1474560;F:163840;F:163840
844 data = fad_control.drs_calibration()
845 N1 = data[0]
846 N3 = data[1:4]
847 OffsetMean = np.array(data[4:4+1024*1440]).reshape(1440,1024)
848 OffsetRms = np.array(data[4+1024*1440:4+1024*1440*2]).reshape(1440,1024)
849 GainMean = np.array(data[4+1024*1440*2:4+1024*1440*3]).reshape(1440,1024)
850 GainRms = np.array(data[4+1024*1440*3:4+1024*1440*4]).reshape(1440,1024)
851
852 gr = GainRms.mean(axis=1)
853 lala = np.zeros(len(gr)/9)
854 for i,v in enumerate(lala):
855 lala[i] = gr[i*9:(i+1)*9].mean()
856
857 # outliers
858 mean = lala.mean()
859 std = lala.std()
860
861 print 'Mean DRS GainRms value:', mean
862 print 'std:', std
863 outs = np.where( lala > mean+7*std)[0]
864 if len(outs) > 0:
865 print 'WARNING possible DRS underflow detected!!!'
866 for out in outs:
867 out = int(out)
868 crate= out/40
869 board = (out-40*crate)/4
870 chip = out-40*crate-4*board
871 print 'possible DRS underflow in DRS:', crate, board, chip, '--> Mean-GainRms:', lala[out]
872 return outs
873 else:
874 return False
875
876
877
878
879def GetBiasCalibration():
880 cali = feedback.calibration()
881 bias_calibration['Time'] = time.time()
882 bias_calibration['Calibration'] = cali
883
884def GetBiasCurrent(verbose = False):
885 """ return median, std, max and min current
886 """
887 if 'Time' in bias_calibration:
888 cali = bias_calibration['Calibration']
889 else:
890 GetBiasCalibration()
891 cali = bias_calibration['Calibration']
892
893 r = np.array(cali[2*416:2*416+320])
894
895 bias = bias_control
896
897 I = np.array(bias.current()[0:320], dtype=float)
898 II = I/4096. * 5000
899 V = np.array(bias.voltage()[0:320])
900 if len(sys.argv) > 1:
901 i = int(sys.argv[1])
902 else: i=0
903# print 'I:', I[i], 'dac\t', II[i], 'uA'
904# print 'V:', V[i]
905# print ''
906# print 'GUI offset:', V[i]/r[i]*1e6
907# print 'GUI feedback:', II[0] - V[0]/r[0]*1e6
908
909 GUII = II-V/r*1e6
910 if verbose:
911 print 'median', np.median(GUII)
912 print 'mean', GUII.mean()
913 # print 'rms', ((GUII- GUII.mean())**2).sum()
914 print 'std', GUII.std()
915 print 'max', GUII.max()
916 print 'min', GUII.min()
917
918 return GUII.mean(), GUII.std(), GUII.max(), GUII.min()
919
920
921
922
923def TrackSourceWobbleX( sourcename, wobble_pos ):
924 """ general Tracking function
925 """
926 wp = int(wobble_pos)
927 if wp != 1 and wp != 2:
928 raise ValueError('wobble_pos *must* be 1 or 2')
929
930 if sourcename not in sourcedict:
931 print sourcedict.keys()
932 raise ValueError('sourcename: '+ sourcename +' must be in sourcedict.')
933
934 print 'moving telescope to wobble position ', wp, 'of ', sourcename
935 print '...waiting for DRIVE_CONTROL'
936 print ' to be in state 6: Armed'
937 drive_control.stop()
938 drive_control.wait(6) #Armed
939 print 'DRIVE: ARMED'
940 time.sleep(5.)
941
942 wobble_offset = sourcedict[sourcename]['wobble_offset']
943 wobble_angle = sourcedict[sourcename]['wobble_angle'+str(wp)]
944 sourcename += '\0'
945
946 last_drive_method = drive_control.track_source
947 last_drive_kwargs = { 'wobble_offset' : wobble_offset,
948 'wobble_angle' : wobble_angle,
949 'source_name' : sourcename }
950 kwa = last_drive_kwargs
951 last_drive_method(kwa['wobble_offset'], kwa['wobble_angle'], kwa['source_name'])
952
953 print '... done'
954
955def TakeSource( name ):
956 if name not in sourcedict:
957 print name, 'not in dict of sources, possible sources are:'
958 print sorted(sourcedict.keys())
959 raise ValueError('wrong source name')
960
961 TrackSourceWobbleX( name, 1) # Track Wobble pos 1 of source
962 WaitForTracking()
963 # Take a DRS-Calibration before beginning to take physics Data
964 TakeDrsCalibration()
965 # check feedback state before switching BIAS ON and ramping up to nominal Voltage
966 PrepareBiasForDataTaking()
967 # taking a Data Set (1x Pedestal 1000 Bias On, 1x LPext 1000, 4x5min DataRun)
968 TakeData()
969 StopTracking()
970
971 TrackSourceWobbleX( name, 2) # Track Wobble pos 2 of source
972 WaitForTracking()
973 # taking a Data Set (1x Pedestal 1000 Bias On, 1x LPext 1000, 4x5min DataRun)
974 TakeData()
975
976 StopTracking()
977
978
979
980
981
982
983def PrintCurrents( x = 1.0):
984 while True:
985 time.sleep( x )
986 print time.strftime('%d %b %Y %H:%M:%S UTC', time.gmtime()), GetBiasCurrent()
987
988
989
990def GetFadConnections( verbose = False ):
991 """ return np.array(40) with bitmaps, showing the FADs connection status:
992 apperently this is the meaning:
993 0x43 -- well connected and well configured -- green with white tick mark
994 0x42 -- well connected -- green
995 0x09 -- something is wrong with the connection -- orange or red?
996 0x00 -- not connected, and not attempting to connect -- grey
997 """
998
999 conn = np.array(map( ord, fad_control.connections()[0] ))
1000 if verbose:
1001 for crate in range(4):
1002 print map( hex, conn[crate*10: (crate+1) *10 ] )
1003 return conn
1004
1005
1006
1007if __name__ == '__main__':
1008 print 'Welcome to PyDimCtrl'
1009 make_sourcedict()
1010 print
1011 print 'possible sources:'
1012 print sorted( sourcedict.keys() )
1013
1014 print 'available Dim Servers'
1015 for dim in dims:
1016 print dim.name,
1017 print
1018
1019
Note: See TracBrowser for help on using the repository browser.