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

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