1 | #!/usr/bin/python -tti
|
---|
2 | from factdimserver import *
|
---|
3 |
|
---|
4 | # List of Wobble Positions
|
---|
5 | source_list = { '1ES 1218+304' : [( 0.6, -5), (0.6, 175)] ,\
|
---|
6 | 'Crab' : [(0.6, 50), (0.6, -130)], \
|
---|
7 | 'Mrk 421' : [(0.6, 90),(0.6, -90)] \
|
---|
8 | 'Mrk 501' : [(0.6, 90),(0.6, -90)] }
|
---|
9 |
|
---|
10 | def TakeFullSet( source = 'Crab', verbose = True):
|
---|
11 | msg = MSG( verbose )
|
---|
12 | drs_calib_done = False # Drs Calib is only done in the 1st wobble pos
|
---|
13 |
|
---|
14 | if not source in source_list:
|
---|
15 | raise ValueError('source not in source_list')
|
---|
16 | msg("Possible sources are:")
|
---|
17 | for src in source_list.keys():
|
---|
18 | msg(src)
|
---|
19 | return False
|
---|
20 |
|
---|
21 |
|
---|
22 | # set is a list of wobble positions, stored as 2-tuple
|
---|
23 | for set in source_list(source):
|
---|
24 | # wobble is a 2-tuple: (Shift, Angle)
|
---|
25 | for wobble in set:
|
---|
26 | TrackSource( source, wobble[0] , wobble[1] , CalmDownTime=45)
|
---|
27 |
|
---|
28 | if not drs_calib_done:
|
---|
29 | TakeDrsAmplitudeCalibration( roi=1024 )
|
---|
30 | TakeDrsTimeCalibration( mode='upshifted' )
|
---|
31 | AddDrsAmplitudeCalibration( roi=300 )
|
---|
32 | drs_calib_done = True
|
---|
33 |
|
---|
34 | VoltageOn( mode='current' )
|
---|
35 | for i in range(4):
|
---|
36 | msg("Taking Data Run "+str(i+1)+" of 4")
|
---|
37 | TakeDataRun()
|
---|
38 | VoltageOff()
|
---|
39 |
|
---|
40 | StopTracking()
|
---|
41 | return True
|
---|
42 |
|
---|
43 | #=========== TRACKING =========================================================
|
---|
44 | def TrackSource( Shift=0.6, Angle=50, SrcName='Crab', CalmDownTime = None, verbose=True):
|
---|
45 | drive = drive_control
|
---|
46 | msg = MSG( verbose )
|
---|
47 | SrcName += '\0'
|
---|
48 |
|
---|
49 | if not StopTracking( timeout = 5, verbose = False ):
|
---|
50 | msg.fail('Cannot start Tracking, because I cannot Stop the Drive')
|
---|
51 | return False
|
---|
52 |
|
---|
53 | drive.track_source( Shift, Angle, SrcName)
|
---|
54 |
|
---|
55 | if CalmDownTime != None:
|
---|
56 | if not WaitToCalmDown( CalmDownTime, verbose = True):
|
---|
57 | msg.fail("a problem in WaitToCalmDown(). drive state: "+drive.sts)
|
---|
58 | return False:
|
---|
59 |
|
---|
60 | msg.ok('Tracking Source '+SrcName + ' Angle:'+str(Angle)+' Shift:'+str(Shift))
|
---|
61 | return True
|
---|
62 |
|
---|
63 | def WaitToCalmDown( CalmDownTime = 45, time_until_moving = 10, time_until_tracking = 40, verbose = True):
|
---|
64 | """ before calling this function, one should call TrackSource()
|
---|
65 | this function waits until Drive is in state 'Tracking'
|
---|
66 | and then sleeps *CalmDownTime* seconds in order to give
|
---|
67 | the Drive time to calm down.
|
---|
68 |
|
---|
69 | """
|
---|
70 | drive = drive_control
|
---|
71 | msg = MSG(verbose)
|
---|
72 |
|
---|
73 | starttime = time.time()
|
---|
74 | while not drive.stn == 6: #Moving
|
---|
75 | if time.time() - starttime > time_until_moving:
|
---|
76 | msg.fail("DRIVE not in Moving after "+str(time_until_moving))
|
---|
77 | return False
|
---|
78 | time.sleep(0.5)
|
---|
79 | msg.ok("Drive is Moving, waiting for Tracking")
|
---|
80 |
|
---|
81 | starttime = time.time()
|
---|
82 | while not drive.stn == 7: #Tracking
|
---|
83 | if time.time() - starttime > time_until_tracking:
|
---|
84 | msg.fail("DRIVE not in Tracking after "+str(time_until_tracking))
|
---|
85 | return False
|
---|
86 | time.sleep(0.5)
|
---|
87 | msg.ok("Drive is Tracking, waiting to calm down...")
|
---|
88 |
|
---|
89 | time.sleep(CalmDownTime)
|
---|
90 | msg.ok("Drive hopefully has calmed down")
|
---|
91 | return True
|
---|
92 |
|
---|
93 | def StopTracking( timeout = 3, verbose = True ):
|
---|
94 | msg = MSG(verbose)
|
---|
95 | drive = drive_control
|
---|
96 | starttime = time.time()
|
---|
97 | while not drive.stn == 5:
|
---|
98 | if time.time() - starttime > timeout:
|
---|
99 | msg.fail('Did not get DRIVE into Armed state within '+str(timeout)+' seconds')
|
---|
100 | return False
|
---|
101 |
|
---|
102 | if drive.stn < 5:
|
---|
103 | msg.fail('DRIVE in state'+drive.sts+" I don't know how to STOP")
|
---|
104 | if drive.stn >= 256:
|
---|
105 | msg.fail('DRIVE in state'+drive.sts+" I don't know how to STOP")
|
---|
106 |
|
---|
107 | if drive.stn in [6,7]:
|
---|
108 | drive.stop()
|
---|
109 | time.sleep(0.5)
|
---|
110 |
|
---|
111 | msg.ok('DRIVE Stopped: current state:'+drive.sts)
|
---|
112 | return True
|
---|
113 |
|
---|
114 | #=========== DRS CALIBRATION ==================================================
|
---|
115 | def TakeDrsAmplitudeCalibration( roi = None, verbose = True):
|
---|
116 | """ Takes DRS Amplitude Calibration
|
---|
117 | *roy* integer: 300, 1024 or
|
---|
118 | *roy* string : 'both'
|
---|
119 | in case of both, the roi=300 calibration is done last.
|
---|
120 |
|
---|
121 | after each complete AmpliteCalibration a 4th pedestal run of the same
|
---|
122 | roi is taken, for crosschecking.
|
---|
123 | """
|
---|
124 | msg = MSG( verbose )
|
---|
125 | bias = bias_control
|
---|
126 | fad = fad_control
|
---|
127 | if not roi in [300,1024,'both']:
|
---|
128 | raise ValueError("roi must be 300,1024 or the string 'both'")
|
---|
129 |
|
---|
130 |
|
---|
131 | bias.set_zero_voltage()
|
---|
132 | if not bias.wait(7, 10):
|
---|
133 | msg.warn("bias has not switched of after 10sec")
|
---|
134 | return False
|
---|
135 |
|
---|
136 | fad.start_drs_calibration()
|
---|
137 | Take( -1, 1000, 'drs-pedestal')
|
---|
138 | Take( -1, 1000, 'drs-gain')
|
---|
139 | if roi == 300:
|
---|
140 | Take( -1, 1000, 'pedestal')
|
---|
141 | fad.set_file_format(2)
|
---|
142 | Take( -1, 1000, 'pedestal')
|
---|
143 | elif roi == 1024:
|
---|
144 | Take( -1, 1000, 'drs-pedestal')
|
---|
145 | fad.set_file_format(2)
|
---|
146 | Take( -1, 1000, 'drs-pedestal')
|
---|
147 | elif roi == 'both':
|
---|
148 | Take( -1, 1000, 'drs-pedestal')
|
---|
149 | fad.set_file_format(2)
|
---|
150 | Take( -1, 1000, 'drs-pedestal')
|
---|
151 | fad.reset_secondary_drs_baseline()
|
---|
152 | Take( -1, 1000, 'pedestal')
|
---|
153 | fad.set_file_format(2)
|
---|
154 | Take( -1, 1000, 'pedestal')
|
---|
155 |
|
---|
156 |
|
---|
157 | def TakeDrsTimeCalibration( mode = 'upshifted', verbose = True):
|
---|
158 | """ Takes DRS Time Calibration
|
---|
159 | *mode* can be 'upshifted', 'old' or 'both'
|
---|
160 | """
|
---|
161 | msg = MSG( verbose )
|
---|
162 | bias = bias_control
|
---|
163 | fad = fad_control
|
---|
164 | if not mode in ['upshifted', 'old', 'both']:
|
---|
165 | raise ValueError("mode must be: 'upshifted','old' or 'both'")
|
---|
166 |
|
---|
167 | bias.set_zero_voltage()
|
---|
168 | if not bias.wait(7, 10):
|
---|
169 | msg.warn("bias has not switched of after 10sec")
|
---|
170 | return False
|
---|
171 |
|
---|
172 | fad.set_file_format(2)
|
---|
173 | if mode == 'old':
|
---|
174 | Take(-1, 1000, 'drs-time')
|
---|
175 | if mode == 'upshifted':
|
---|
176 | Take(-1, 1000, 'drs-time-upshifted')
|
---|
177 | if mode == 'both':
|
---|
178 | Take(-1, 1000, 'drs-time')
|
---|
179 | Take(-1, 1000, 'drs-time-upshifted')
|
---|
180 |
|
---|
181 |
|
---|
182 |
|
---|
183 | def AddDrsAmplitudeCalibration( roi = None, verbose = True):
|
---|
184 | """ Adds a DRS Amplitude Calibration,
|
---|
185 | do not call, in case you did not *Take* one before
|
---|
186 | *roy* integer: 300, 1024
|
---|
187 |
|
---|
188 | after each complete AmpliteCalibration a 4th pedestal run of the same
|
---|
189 | roi is taken, for crosschecking.
|
---|
190 | """
|
---|
191 | msg = MSG( verbose )
|
---|
192 | bias = bias_control
|
---|
193 | fad = fad_control
|
---|
194 | if not roi in [300,1024]:
|
---|
195 | raise ValueError("roi must be 300,1024")
|
---|
196 |
|
---|
197 | if not bias.stn == 'VoltageOff':
|
---|
198 | msg.fail('a DRS amplitude calibration should not be taken with Voltage On')
|
---|
199 | return False
|
---|
200 |
|
---|
201 | fad.reset_secondary_drs_baseline()
|
---|
202 | if roi == 300
|
---|
203 | Take( -1, 1000, 'pedestal')
|
---|
204 | fad.set_file_format(2)
|
---|
205 | Take( -1, 1000, 'pedestal')
|
---|
206 | elif roi == 1024:
|
---|
207 | Take( -1, 1000, 'drs-pedestal')
|
---|
208 | fad.set_file_format(2)
|
---|
209 | Take( -1, 1000, 'drs-pedestal')
|
---|
210 |
|
---|
211 | return True
|
---|
212 |
|
---|
213 |
|
---|
214 | #============ BIAS VOLTAGE ====================================================
|
---|
215 | time_of_last_overcurrent = -1. * float('inf')
|
---|
216 | number_of_overcurrent_occurences = 0
|
---|
217 |
|
---|
218 | def VoltageOn( mode = None, Watchdog = None, timeout = 30, verbose = True):
|
---|
219 | """ High Level Method for switching on the bias Voltage
|
---|
220 | can be called, in whatever state the bias and the feedback might be.
|
---|
221 | In case the voltage is on and the feedback is already in the mode
|
---|
222 | requested, nothing happens.
|
---|
223 | In all other cases, the method will perform the needed steps to switch
|
---|
224 | on the bias voltage, the way the user requested
|
---|
225 | """
|
---|
226 | msg = MSG( verbose )
|
---|
227 | bias = bias_control
|
---|
228 | fb = feedback
|
---|
229 |
|
---|
230 | if not mode in ['temperature', 'current', 'feedback']:
|
---|
231 | raise ValueError("mode must be 'temperature', 'current' or 'feedback'")
|
---|
232 |
|
---|
233 | if mode == 'temperature':
|
---|
234 | fb_target = 10 #TempControl
|
---|
235 | elif mode == 'feedback':
|
---|
236 | fb_target = 11 # FeedbackControl
|
---|
237 | elif mode == 'current':
|
---|
238 | fb_target = 12 #CurrentControl
|
---|
239 |
|
---|
240 | bias_target = 9 # VoltageOn
|
---|
241 |
|
---|
242 | starttime = time.time()
|
---|
243 |
|
---|
244 | while not ((bias.stn == bias_target) and (fb.stn == fb_target)):
|
---|
245 | if time.time() - starttime > timeout:
|
---|
246 | msg.fail("VoltageOn did not succeed after "+str(timeout)+' seconds')
|
---|
247 | return False
|
---|
248 |
|
---|
249 | elif fb.stn == fb_target-3: # everything fine, but output disabled
|
---|
250 | fb.enable_output(1)
|
---|
251 | bias.set_global_dac(1)
|
---|
252 |
|
---|
253 | elif fb.stn == fb_target and bias.stn == 5: # feedback ok, but we are Ramping
|
---|
254 | # lets try to wait
|
---|
255 | time.sleep(0.5)
|
---|
256 |
|
---|
257 | elif bias.stn == 1: #Disconnected
|
---|
258 | bias.reconnect()
|
---|
259 |
|
---|
260 | elif bias.stn == 6: # Overcurrent
|
---|
261 | if number_of_overcurrent_occurences < 3:
|
---|
262 | bias.set_zero_voltage()
|
---|
263 | bias.reset_over_current_status()
|
---|
264 | elif time.time() - time_of_last_overcurrent > 60:
|
---|
265 | number_of_overcurrent_occurences = 0
|
---|
266 |
|
---|
267 | number_of_overcurrent_occurences += 1
|
---|
268 | time_of_last_overcurrent = time.time()
|
---|
269 |
|
---|
270 | elif bias.stn == 7: # VoltageOff
|
---|
271 | bias.set_global_dac(1)
|
---|
272 |
|
---|
273 | elif bias.stn == 8: # NotReferenced
|
---|
274 | bias.set_zero_voltage()
|
---|
275 | bias.set_global_dac(1)
|
---|
276 |
|
---|
277 |
|
---|
278 | else:
|
---|
279 | # if nothing was done. sleep a while
|
---|
280 | time.sleep(0.5)
|
---|
281 |
|
---|
282 |
|
---|
283 |
|
---|
284 |
|
---|
285 | msg("waiting 45sec...")
|
---|
286 | time.sleep(45)
|
---|
287 | return True
|
---|
288 |
|
---|
289 |
|
---|
290 |
|
---|
291 | def VoltageOff
|
---|
292 | def std_bias_watchdog( state, verbose=True ):
|
---|
293 | msg = MSG(verbose)
|
---|
294 | if state == 1: #Disconnected
|
---|
295 | msg.warn("BIAS just DISCONNECTED .. trying to reconnect")
|
---|
296 | msg.warn("current runnumber:"+fad_control.runnumber() )
|
---|
297 | bias.reconnect()
|
---|
298 | time.sleep(1)
|
---|
299 | bias.set_zero_voltage()
|
---|
300 | # TODO: This should work, but it is stupid.
|
---|
301 | bias.reset_over_current_status()
|
---|
302 | bias.reset_over_current_status()
|
---|
303 | bias.set_zero_voltage()
|
---|
304 | bias.reset_over_current_status()
|
---|
305 | bias.set_global_dac(1)
|
---|
306 |
|
---|
307 |
|
---|
308 | def IsReadyForDataTaking( verbose = True ):
|
---|
309 | drive = drive_control
|
---|
310 | bias = bias_control
|
---|
311 | fad = fad_control
|
---|
312 |
|
---|
313 | msg = MSG()
|
---|
314 | msg.output = verbose
|
---|
315 | msg("Checking if System isready for data taking... ")
|
---|
316 |
|
---|
317 | ok = True
|
---|
318 | if not drive.stn == 7:
|
---|
319 | msg.warn(drive.name + ':' + drive.sts + " NOT ok")
|
---|
320 | ok = False
|
---|
321 | else:
|
---|
322 | msg.ok(drive.name + ':' + drive.sts + " OK")
|
---|
323 |
|
---|
324 | if not feedback.stn == 12:
|
---|
325 | msg.warn(feedback.name +':'+ feedback.sts + " NOT ok")
|
---|
326 | ok = False
|
---|
327 | else:
|
---|
328 | msg.ok(feedback.name +':'+ feedback.sts + " OK")
|
---|
329 |
|
---|
330 | if not bias.stn == 9:
|
---|
331 | msg.warn(bias.name +':'+ bias.sts + " NOT ok")
|
---|
332 | ok = False
|
---|
333 | else:
|
---|
334 | msg.ok(bias.name +':'+ bias.sts + " OK")
|
---|
335 |
|
---|
336 | if not fad.stn == 4:
|
---|
337 | msg.warn(fad.name +':'+ fad.sts + " NOT ok")
|
---|
338 | ok = False
|
---|
339 | else:
|
---|
340 | msg.ok(fad.name +':'+ fad.sts + " ok")
|
---|
341 |
|
---|
342 |
|
---|
343 | if ok:
|
---|
344 | msg.ok( " all ok " )
|
---|
345 |
|
---|
346 | return ok
|
---|
347 |
|
---|
348 | def TakeDataRun( verbose = True ):
|
---|
349 | fad = fad_control
|
---|
350 | msg = MSG()
|
---|
351 | msg.output = verbose
|
---|
352 | if not IsReadyForDataTaking( verbose=False ):
|
---|
353 | msg.fail("System not Ready for DataTaking")
|
---|
354 | IsReadyForDataTaking( verbose=True )
|
---|
355 | return False
|
---|
356 | mcp.start(300,-1,'data\0')
|
---|
357 | if not fad.wait(8, 10):
|
---|
358 | msg.warn("FAD not in Writing Data after 10seconds")
|
---|
359 | return False
|
---|
360 | msg("... taking data: 300 seconds - normal data run")
|
---|
361 | if not fad.wait(4, 330):
|
---|
362 | msg.warn("FAD did not return to Connected, after 330 seconds")
|
---|
363 | return False
|
---|
364 | return True
|
---|
365 |
|
---|
366 | def TakePedestalOnRun( verbose = True ):
|
---|
367 | msg = MSG()
|
---|
368 | msg.output = verbose
|
---|
369 | if not IsReadyForDataTaking( verbose=False ):
|
---|
370 | msg.fail("System not Ready for DataTaking")
|
---|
371 | IsReadyForDataTaking( verbose=True )
|
---|
372 | return False
|
---|
373 | mcp.start(-1,1000,'pedestal\0')
|
---|
374 | if not fad.wait(8, 10):
|
---|
375 | msg.warn("FAD not in Writing Data after 10seconds")
|
---|
376 | return False
|
---|
377 | msg("... taking ped: 1000evts @25Hz")
|
---|
378 | if not fad.wait(4, 50):
|
---|
379 | msg.warn("FAD did not return to Connected, after 50 seconds")
|
---|
380 | return False
|
---|
381 | return True
|
---|
382 |
|
---|
383 | def TakeExtLpRun( verbose = True ):
|
---|
384 | msg = MSG()
|
---|
385 | msg.output = verbose
|
---|
386 | if not IsReadyForDataTaking( verbose=False ):
|
---|
387 | msg.fail("System not Ready for DataTaking")
|
---|
388 | IsReadyForDataTaking( verbose=True )
|
---|
389 | return False
|
---|
390 | mcp.start(-1,1000,'light-pulser-ext\0')
|
---|
391 | if not fad.wait(8, 10):
|
---|
392 | msg.warn("FAD not in Writing Data after 10seconds")
|
---|
393 | return False
|
---|
394 | msg("... taking light-pulser-ext: 1000evts @25Hz")
|
---|
395 | if not fad.wait(4, 50):
|
---|
396 | msg.warn("FAD did not return to Connected, after 50 seconds")
|
---|
397 | return False
|
---|
398 | return True
|
---|
399 |
|
---|
400 | def TakeData( verbose = True):
|
---|
401 | msg = MSG()
|
---|
402 | msg.output = verbose
|
---|
403 | TakePedestalOnRun()
|
---|
404 | TakeExtLpRun()
|
---|
405 | for i in range(4):
|
---|
406 | i +=1
|
---|
407 | msg("Taking Data Run "+str(i)+" of 4")
|
---|
408 | TakeDataRun()
|
---|
409 |
|
---|
410 | def Take( time=0, events=0, runtype='drs-pedestal', verbose=True):
|
---|
411 | msg = MSG( verbose )
|
---|
412 | fad = fad_control
|
---|
413 | runtype += '\0'
|
---|
414 | if not fad.wait(4, 10):
|
---|
415 | msg.warn("fad not connected after 10sec")
|
---|
416 | return False
|
---|
417 | mcp.start( time, events, runtype)
|
---|
418 | if not fad.wait(8, 30):
|
---|
419 | msg.warn("fad not Writing Data after 30sec")
|
---|
420 | return False
|
---|
421 | timeout = float('inf')
|
---|
422 | if time != -1:
|
---|
423 | timeout = time*1.1
|
---|
424 | if not fad.wait(4, timeout):
|
---|
425 | msg.warn("Data Writing not finished after "+str(timeout)+"sec")
|
---|
426 | return False
|
---|
427 | return True
|
---|
428 |
|
---|
429 |
|
---|
430 | def BlinkenLights(verbose = True):
|
---|
431 | msg = MSG(verbose)
|
---|
432 | fad = fad_control
|
---|
433 |
|
---|
434 | for i in range(10):
|
---|
435 | fad.set_file_format(2)
|
---|
436 | time.sleep(1)
|
---|
437 | fad.set_file_format(0)
|
---|
438 | time.sleep(1)
|
---|
439 |
|
---|
440 |
|
---|
441 |
|
---|
442 |
|
---|
443 | #==============================================================================
|
---|
444 | def Connect():
|
---|
445 | prepare_ftm_control()
|
---|
446 | prepare_fsc_control()
|
---|
447 | feedback.stop()
|
---|
448 | prepare_bias_control()
|
---|
449 | prepare_feedback()
|
---|
450 | prepare_data_logger()
|
---|
451 |
|
---|
452 | def prepare_fsc_control( verbose = True, timeout = 10, delay = 0.2):
|
---|
453 | msg = MSG( verbose )
|
---|
454 | fsc = fsc_control
|
---|
455 | start_time = time.time()
|
---|
456 | if timeout == None:
|
---|
457 | timeout = float('inf')
|
---|
458 | if delay < 0.:
|
---|
459 | delay = 0.
|
---|
460 |
|
---|
461 | while not fsc.stn == 2: #Connected
|
---|
462 | if time.time() > start_time + timeout:
|
---|
463 | return False
|
---|
464 |
|
---|
465 | if (fsc.stn <= 0) or (fsc.stn >= 256):
|
---|
466 | msg.fail("FSC_CONTROL is in state "+fsc.sts)
|
---|
467 | msg.fail(prepare_fsc_control.__name__ + "does not know how to handle this")
|
---|
468 | return False
|
---|
469 | elif fsc.stn == 1: # Disconnected
|
---|
470 | fsc.reconnect()
|
---|
471 | return True
|
---|
472 |
|
---|
473 | def prepare_ftm_control( verbose = True, timeout = 10, delay = 0.2):
|
---|
474 | msg = MSG( verbose )
|
---|
475 | ftm = ftm_control
|
---|
476 | start_time = time.time()
|
---|
477 | if timeout == None:
|
---|
478 | timeout = float('inf')
|
---|
479 | if delay < 0.:
|
---|
480 | delay = 0.
|
---|
481 |
|
---|
482 | while not ftm.stn == 3:
|
---|
483 | if time.time() > start_time + timeout:
|
---|
484 | return False
|
---|
485 |
|
---|
486 | if (ftm.stn <= 0) or (ftm.stn >= 256):
|
---|
487 | msg.fail("FMT_CONTROL is in state "+ftm.sts)
|
---|
488 | msg.fail("ftm_to_Idle() does not know how to handle this")
|
---|
489 | return False
|
---|
490 | elif ftm.stn == 1: # Disconnected
|
---|
491 | ftm.reconnect()
|
---|
492 | elif ftm.stn == 2: #Connected
|
---|
493 | # just wait a second
|
---|
494 | time.sleep(1)
|
---|
495 | elif ftm.stn == 4: #TriggerOn
|
---|
496 | ftm.enable_trigger(0) #switch trigger off
|
---|
497 | elif ftm.stn in [5,6,7]: # some Configure state
|
---|
498 | ftm.reset_configure()
|
---|
499 |
|
---|
500 | return True
|
---|
501 |
|
---|
502 | def prepare_data_logger( verbose = True, timeout = 10, delay = 0.2):
|
---|
503 | msg = MSG(verbose)
|
---|
504 | dl = data_logger
|
---|
505 | if timeout == None:
|
---|
506 | timeout = float('inf')
|
---|
507 | if delay < 0.:
|
---|
508 | delay = 0.
|
---|
509 | start_time = time.time()
|
---|
510 | raise NotImplementedError('prepare_data_logger() is not yet implemented')
|
---|
511 |
|
---|
512 | def prepare_fad_control( verbose = True, timeout = 10, delay = 0.2):
|
---|
513 | msg = MSG(verbose)
|
---|
514 | fad = fad_control
|
---|
515 | ftm = ftm_control
|
---|
516 | if timeout == None:
|
---|
517 | timeout = float('inf')
|
---|
518 | if delay < 0.:
|
---|
519 | delay = 0.
|
---|
520 | start_time = time.time()
|
---|
521 |
|
---|
522 | while not fad.stn == 4:
|
---|
523 | # Timeout
|
---|
524 | if time.time() > start_time + timeout:
|
---|
525 | msg.fail("Timeout in " + prepare_fad_control.__name__)
|
---|
526 | return False
|
---|
527 | # Strange States
|
---|
528 | if (fad.stn <= 0) or (fad.stn >= 256):
|
---|
529 | msg.fail("FAD_CONTROL is in state "+fad.sts)
|
---|
530 | msg.fail(prepare_fad_control.__name__ + "does not know how to handle this")
|
---|
531 | return False
|
---|
532 | elif fad.stn == 1: # Disengaged
|
---|
533 | fad.start()
|
---|
534 | elif fad.stn == 2: # Disconnected
|
---|
535 | fad.start()
|
---|
536 | elif fad.stn == 3: # Connecting
|
---|
537 | # it might just need time
|
---|
538 | if time.time() - fad.last_st_change < 5:
|
---|
539 | time.sleep(2)
|
---|
540 | timeout += 1
|
---|
541 | else:
|
---|
542 | # there might be a problem with one of the boards
|
---|
543 | conns = map( ord, fad.connections()[0] )
|
---|
544 | problems = {}
|
---|
545 | for fad,conn in enumerate(conns):
|
---|
546 | if conn < 255:
|
---|
547 | print "FAD:", fad, "has a problem"
|
---|
548 | if not fad/10 in problems:
|
---|
549 | problems[fad/10] = []
|
---|
550 | else:
|
---|
551 | problems[fad/10].append( fad%10 )
|
---|
552 |
|
---|
553 | for fad in range(10):
|
---|
554 | for crate in problems.keys():
|
---|
555 | fad.disconnect(crate*10+fad)
|
---|
556 | ftm.toggle_ftu(crate*10+fad)
|
---|
557 | for crate in problems.keys():
|
---|
558 | time.sleep(1)
|
---|
559 | ftm.reset_crate(crate)
|
---|
560 |
|
---|
561 | for fad in range(10):
|
---|
562 | for crate in problems.keys():
|
---|
563 | time.sleep(3.5)
|
---|
564 | fad.connect(crate*10+fad)
|
---|
565 | ftm.toggle_ftu(crate*10+fad)
|
---|
566 |
|
---|
567 | elif fad.stn == 5: # Configuring1
|
---|
568 | if time.time() - fad.last_st_change < 5:
|
---|
569 | time.sleep(1)
|
---|
570 | else:
|
---|
571 | msg.warn("FAD is in Configuring1 since more than 5sec")
|
---|
572 |
|
---|
573 | elif fad.stn == 6: # Configuring2
|
---|
574 | if time.time() - fad.last_st_change < 5:
|
---|
575 | time.sleep(1)
|
---|
576 | else:
|
---|
577 | msg.warn("FAD is in Configuring2 since more than 5sec")
|
---|
578 |
|
---|
579 | elif fad.stn == 7: # Configured
|
---|
580 | if time.time() - fad.last_st_change < 5:
|
---|
581 | time.sleep(1)
|
---|
582 | else:
|
---|
583 | msg.warn("FAD is in Configuring2 since more than 5sec")
|
---|
584 |
|
---|
585 | elif fad.stn == 8: #WritingData
|
---|
586 | # I don't know how to get from WritingData to Connected
|
---|
587 | # well. .. one could wait for a timeout, but I hate that.
|
---|
588 | fad.close_open_files()
|
---|
589 |
|
---|
590 |
|
---|
591 | time.sleep(delay)
|
---|
592 | return True
|
---|
593 |
|
---|
594 | def prepare_bias_control( verbose = True, timeout = 10, delay = 0.2):
|
---|
595 | msg = MSG(verbose)
|
---|
596 | bias = bias_control
|
---|
597 |
|
---|
598 | if timeout == None:
|
---|
599 | timeout = float('inf')
|
---|
600 | if delay < 0.:
|
---|
601 | delay = 0.
|
---|
602 | start_time = time.time()
|
---|
603 |
|
---|
604 | while (bias.stn != 4) and (bias.stn != 7): #Connected or VoltageOff
|
---|
605 | # Timeout
|
---|
606 | if time.time() > start_time + timeout:
|
---|
607 | msg.fail("Timeout in " + prepare_bias_control.__name__)
|
---|
608 | return False
|
---|
609 | # Strange States
|
---|
610 | if (bias.stn <= 0) or (bias.stn >= 256):
|
---|
611 | msg.fail("BIAS_CONTROL is in state "+bias.sts)
|
---|
612 | msg.fail(prepare_bias_control.__name__ + "does not know how to handle this")
|
---|
613 | return False
|
---|
614 | elif bias.stn == 1: # Disconnected
|
---|
615 | bias.reconnect()
|
---|
616 | elif bias.stn == 2: # Connecting
|
---|
617 | if time.time() - bias.last_st_change < 5:
|
---|
618 | time.sleep(1)
|
---|
619 | else:
|
---|
620 | msg.warn("BIAS_CONTROL is in Connecting since more than 5sec")
|
---|
621 | elif bias.stn == 3: # Initializing
|
---|
622 | if time.time() - bias.last_st_change < 5:
|
---|
623 | time.sleep(1)
|
---|
624 | else:
|
---|
625 | msg.warn("BIAS_CONTROL is in Initializing since more than 5sec")
|
---|
626 | elif bias.stn == 5: #Ramping
|
---|
627 | if time.time() - bias.last_st_change < 10:
|
---|
628 | time.sleep(1)
|
---|
629 | else:
|
---|
630 | msg.warn("BIAS_CONTROL is in Ramping since more than 10sec")
|
---|
631 | bias.stop()
|
---|
632 | elif bias.stn == 6: #OverCurrent
|
---|
633 | time.sleep(0.5)
|
---|
634 | bias.set_zero_voltage()
|
---|
635 | time.sleep(0.5)
|
---|
636 | bias.reset_over_current_status()
|
---|
637 | time.sleep(0.5)
|
---|
638 | elif bias.stn == 8: #NotReferenced
|
---|
639 | time.sleep(0.5)
|
---|
640 | bias.set_zero_voltage()
|
---|
641 | time.sleep(0.5)
|
---|
642 | elif bias.stn == 9: # VoltageOn
|
---|
643 | time.sleep(0.5)
|
---|
644 | bias.set_zero_voltage()
|
---|
645 | time.sleep(0.5)
|
---|
646 | elif bias.stn == 10: # ExpoertMode
|
---|
647 | msg.fail("BIAS is in ExportMode ... wtf")
|
---|
648 | return False
|
---|
649 |
|
---|
650 | time.sleep(delay)
|
---|
651 | return True
|
---|
652 |
|
---|
653 | def prepare_feedback( verbose = True, timeout = 10, delay = 0.2):
|
---|
654 | msg = MSG(verbose)
|
---|
655 | fb = feedback
|
---|
656 | if timeout == None:
|
---|
657 | timeout = float('inf')
|
---|
658 | if delay < 0.:
|
---|
659 | delay = 0.
|
---|
660 | start_time = time.time()
|
---|
661 |
|
---|
662 | while not fb.stn == 6: #Connected
|
---|
663 | # Timeout
|
---|
664 | if time.time() > start_time + timeout:
|
---|
665 | msg.fail("Timeout in " + prepare_feedback.__name__)
|
---|
666 | return False
|
---|
667 | # Strange States
|
---|
668 | if (fb.stn <= 1) or (fb.stn >= 256):
|
---|
669 | msg.fail("FEEDBACK is in state "+fb.sts)
|
---|
670 | msg.fail(prepare_feedback.__name__ + "does not know how to handle this")
|
---|
671 | return False
|
---|
672 | elif fb.stn in [2,3,4,5]:
|
---|
673 | if time.time() - fb.last_st_change < 10:
|
---|
674 | time.sleep(1)
|
---|
675 | else:
|
---|
676 | msg.warn("BIAS_CONTROL is in "+fb.sts+" since more than 10sec")
|
---|
677 |
|
---|
678 | elif fb.stn in [7,8,9]:
|
---|
679 | fb.stop()
|
---|
680 |
|
---|
681 | elif fb.stn in [10,11,12]:
|
---|
682 | fb.enable_output(0)
|
---|
683 | fb.stop()
|
---|
684 |
|
---|
685 | elif fb.stn == 13:
|
---|
686 | # maybe waiting helps
|
---|
687 | if time.time() - fb.last_st_change < 20:
|
---|
688 | time.sleep(1)
|
---|
689 | else:
|
---|
690 | msg.warn("FEEDBACK is in "+fb.sts+" since more than 20sec \n sending STOP")
|
---|
691 | fb.stop()
|
---|
692 |
|
---|
693 | time.sleep(delay)
|
---|
694 | return True
|
---|
695 |
|
---|
696 |
|
---|
697 |
|
---|
698 | #==============================================================================
|
---|
699 | # standard watchdog:
|
---|
700 | def std_bias_watchdog( state, verbose=True ):
|
---|
701 | msg = MSG(verbose)
|
---|
702 | if state == 1: #Disconnected
|
---|
703 | msg.warn("BIAS just DISCONNECTED .. trying to reconnect")
|
---|
704 | msg.warn("current runnumber:"+fad_control.runnumber() )
|
---|
705 | bias.reconnect()
|
---|
706 | time.sleep(1)
|
---|
707 | bias.set_zero_voltage()
|
---|
708 | # TODO: This should work, but it is stupid.
|
---|
709 | bias.reset_over_current_status()
|
---|
710 | bias.reset_over_current_status()
|
---|
711 | bias.set_zero_voltage()
|
---|
712 | bias.reset_over_current_status()
|
---|
713 | bias.set_global_dac(1)
|
---|
714 |
|
---|
715 | # create introduction:
|
---|
716 | class INTRO(object):
|
---|
717 | def __init__(self):
|
---|
718 | # nothing to do
|
---|
719 | pass
|
---|
720 |
|
---|
721 | def __repr__(self):
|
---|
722 | print "welcome to PyDimCtrl V0.1:"
|
---|
723 | print "--------------------------"
|
---|
724 | print "If the hardware is ON but not all the software is connected try:"
|
---|
725 | print " Connect()"
|
---|
726 | print "If all the programs are already up and running, you might want to"
|
---|
727 | print " TakeDrsAmplitudeCalibration(roi=1024) or "
|
---|
728 | print " TakeDrsAmplitudeCalibration(roi=300)"
|
---|
729 | print " i.e. ped, gain, trigger_offset + extra ped(for X-check)"
|
---|
730 | print " TakeDrsTimeCalibration( type='upshifted' ) or "
|
---|
731 | print " TakeDrsTimeCalibration( type='old' ) or "
|
---|
732 | print " "
|
---|
733 | print "In case you would like to ramp up the Bias voltage try:"
|
---|
734 | print " VoltageOn( mode='temperature' ) or"
|
---|
735 | print " VoltageOn( mode='current' ) or"
|
---|
736 | print " VoltageOn( mode='light_pulser' )"
|
---|
737 | print "Switch off with:"
|
---|
738 | print " VoltageOff()"
|
---|
739 | print ""
|
---|
740 | print "In case you would like a Watchdog to check, if the Voltage is up"
|
---|
741 | print "and the BiasCrate is not disconnected, then try:"
|
---|
742 | print " VoltageOn( mode='--see above--', Watchdog=True )"
|
---|
743 | print "PLEASE NOTE: The Watchdog will monitor the State of BIAS_CONTROL"
|
---|
744 | print "and in case of a connection loss, it will: "
|
---|
745 | print " * print a warning"
|
---|
746 | print " * issue a the RECONNECT command"
|
---|
747 | print " * issue SET_ZERO_VOLTAGE - since this is the only way to get referenced"
|
---|
748 | print " * Ramp up again, using the same settings as before"
|
---|
749 | print " * possible OverCurrent situation will be treated as usual"
|
---|
750 | print "The Watchdog will not react on any other state change, like OverCurrent or VoltageOff"
|
---|
751 | print ""
|
---|
752 | print ""
|
---|
753 | return ""
|
---|
754 |
|
---|
755 |
|
---|
756 | intro = INTRO()
|
---|
757 |
|
---|
758 | if __name__ == '__main__':
|
---|
759 | print "welcome:"
|
---|
760 | print " type: intro"
|
---|
761 | print " for a short introduction"
|
---|
762 |
|
---|
763 |
|
---|
764 | #IsReadyForDataTaking()
|
---|
765 | #TrackSource( Shift=0.6, Angle=50, SrcName='Crab', verbose=True)
|
---|
766 | #WaitForTracking( CalmDownTime = 30, verbose = True)
|
---|
767 | #TakeDataRun()
|
---|
768 | #StopTracking()
|
---|