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