Changeset 14659
- Timestamp:
- 11/19/12 12:10:01 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
fact/tools/PyDimCtrl/ScriptsForPyDimCtrl.py
r14466 r14659 6 6 import types 7 7 import sys 8 import threading 9 import Queue 10 11 import logging 12 # create logger with 'spam_application' 13 logger = logging.getLogger('PyDimCtrl') 14 logger.setLevel(logging.DEBUG) 15 # create file handler which logs even debug messages 16 fh = logging.FileHandler('PyDimCtrl.log') 17 fh.setLevel(logging.DEBUG) 18 # create console handler with a higher log level 19 ch = logging.StreamHandler() 20 ch.setLevel(logging.WARNING) 21 # create formatter and add it to the handlers 22 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 23 fh.setFormatter(formatter) 24 ch.setFormatter(formatter) 25 # add the handlers to the logger 26 logger.addHandler(fh) 27 logger.addHandler(ch) 8 28 9 29 last_drive_kwargs = {} … … 11 31 12 32 bias_calibration = {} 33 34 bias_current = {} 13 35 14 36 report_length = 0 … … 26 48 ["IC 310", 0.6, -18, -18+180 ], 27 49 ["PKS 2155-304", 0.6, 90, -90 ] ] 50 51 crazyPatches = [66,191,193] 28 52 29 53 sourcedict = {} … … 117 141 print "connecting to crate", cratenum 118 142 for i in range(cratenum*10, (cratenum+1)*10 ): 119 print 'disconnecting from i', time.time()143 print 'disconnecting from ', i 120 144 fad_control.disconnect(i) 121 145 print "... done" … … 310 334 311 335 336 312 337 def Take( time, num_events, runtype, verbose=False): 313 338 """ more general version of e.g. TakePedestalOnRun … … 337 362 """ 338 363 if Bias not in [None, 'On', 'Off']: 339 raise ValueError('Bias needs to be one of [None, 'On', 'Off']') 364 raise ValueError('Bias needs to be one of [None, "On", "Off"]') 365 return False 366 367 # Sanity check 368 # Drive can be: 369 # Drive = 'sourcename' 370 # Drive = ('sourcename', wobble_pos = 1 || 2) 371 # Drive = None 372 if type(Drive) not in [type(''), type((0,0)), type(None) ]: 373 raise ValueError('Bias needs to be one of [None, "On", "Off"]') 340 374 return False 341 375 … … 380 414 # 381 415 # In case Drive is None no commands will be send to DRIVE_CONTROL at allow 416 417 # Drive can be: 418 # Drive = 'sourcename' 419 # Drive = ('sourcename', wobble_pos = 1 || 2) 420 # Drive = None 382 421 383 422 # RATE_CTRL … … 430 469 duration = 20. 431 470 if Bias == 'On': 432 if (bias_control.voltage()[0:320].mean() > 60) and 433 ( (bias_control.stn == 5) or (bias_control.stn == 9) ) 471 if ( (bias_control.voltage()[0:320].mean() > 60) and 472 ( (bias_control.stn == 5) or 473 (bias_control.stn == 9) ) ): 474 pass 434 475 435 476 elif Bias == 'Off': 436 477 pass 437 478 438 479 if verbose: … … 456 497 # take a Pedestal run 457 498 IsReadyForDataTaking() 458 print 'taking External Light Pulser with BIAS on 1000 ...'499 print 'taking pedestal run with 1000 events' 459 500 Take(-1, 1000, 'pedestal') 460 501 … … 541 582 542 583 def FirstDrsCalib( SkipCurrentCalib=False ): 584 logger = logging.getLogger('PyDimCtrl.FDC') 543 585 """ performs the everything, which is done in the FirstDrsCalib Script as well . 544 586 """ … … 549 591 # Since we do not know, what the feedback program is doing at the moment, we should as well, 550 592 # tell it to keep its mouth shut ... just to be sure, we know whats going on 551 print "stopping feedback"593 logger.debug("stopping feedback") 552 594 feedback.stop() 553 595 554 596 time.sleep(2) 555 597 # stopping should always be possible, and end in state 'Connected'(6) 556 print " ...waiting for FEEDBACK to be in state 6: Connected" 598 599 logger.debug(" ...waiting for FEEDBACK to be in state 6: Connected") 600 print 557 601 feedback.wait(6) 558 602 print "..done" … … 628 672 # and a second pedestal run, with the same ROI as our next data will be, i.e. ROI=300 in this case 629 673 print "taking DRS:Pedestal 1000 ..." 630 print "==================================================="631 print "OPERATOR: "632 print "observe Events tab and make sure there are no patches "633 print "with strange behaviour, which can be caused "634 print "by DRS-CHIP Problems"635 print "==================================================="674 #print "===================================================" 675 #print "OPERATOR: " 676 #print "observe Events tab and make sure there are no patches " 677 #print "with strange behaviour, which can be caused " 678 #print "by DRS-CHIP Problems" 679 #print "===================================================" 636 680 637 681 fad_control.start_drs_calibration() … … 669 713 # the feedback should be in state 'CurrentControl'(12) now 670 714 # the feedback should be in state 'CurrentCtrlIdle'(9) now since 30.05.12 671 print "...waiting for FEEDBACK to be in state 9: CurrentCtrlIdle"672 feedback.wait( 9)715 print "...waiting for FEEDBACK to be in state 12: CurrentControl" 716 feedback.wait(12) 673 717 print "... done" 674 718 print "switching on bias" … … 874 918 return False 875 919 876 877 878 879 920 def GetBiasCalibration(): 880 921 cali = feedback.calibration() … … 882 923 bias_calibration['Calibration'] = cali 883 924 884 def GetBiasCurrent(verbose = False):925 def _GetBiasCurrent_Raw(verbose = False): 885 926 """ return median, std, max and min current 886 927 """ … … 907 948 # print 'GUI feedback:', II[0] - V[0]/r[0]*1e6 908 949 950 # GUII means current(I) as it is written in the GUI :-) 951 # read: GUI-I :-) 909 952 GUII = II-V/r*1e6 910 953 if verbose: … … 916 959 print 'min', GUII.min() 917 960 918 return GUII.mean(), GUII.std(), GUII.max(), GUII.min() 919 920 961 bias_current['Time'] = time.time() 962 bias_current['raw_patch_current'] = GUII 963 return GUII 964 965 def GetPatchCurrents(crazyPatches=crazyPatches ,verbose = False, max_age_sec=1. ): 966 967 if 'Time' in bias_current: 968 if time.time() - bias_current['Time'] > max_age_sec: 969 raw_cur = _GetBiasCurrent_Raw() 970 else: 971 raw_cur = bias_current['raw_patch_current'] 972 else: 973 raw_cur = _GetBiasCurrent_Raw() 974 975 if crazyPatches is None: 976 return raw_cur 977 else: 978 try: 979 crazyPatches = list(crazyPatches) 980 except: 981 raise 982 goodPatches = [x for x in range(320) if x not in crazyPatches] 983 return raw_cur[goodPatches] 984 985 def GetPixelCurrents(crazyPatches=crazyPatches ,verbose = False, max_age_sec=1. ): 986 987 if 'Time' in bias_current: 988 if time.time() - bias_current['Time'] > max_age_sec: 989 raw_cur = _GetBiasCurrent_Raw() 990 else: 991 raw_cur = bias_current['raw_patch_current'] 992 else: 993 raw_cur = _GetBiasCurrent_Raw() 994 995 pixel_cur = np.zeros(len(raw_cur)) 996 for i in range(len(raw_cur)): 997 if i/2: 998 pixel_cur[i] = raw_cur[i]/5. 999 else: 1000 pixel_cur[i] = raw_cur[i]/4. 1001 1002 if crazyPatches is None: 1003 return pixel_cur 1004 else: 1005 try: 1006 crazyPatches = list(crazyPatches) 1007 except: 1008 raise 1009 goodPatches = [x for x in range(320) if x not in crazyPatches] 1010 return pixel_cur[goodPatches] 1011 1012 def PrintPixelCurrents( delay = 4.0): 1013 while True: 1014 time.sleep( delay ) 1015 current = GetPixelCurrents() 1016 interesting = current.min(), np.median(current), current.mean(), current.max() 1017 print time.strftime('%d %b %Y %H:%M:%S UTC', time.gmtime()), interesting 921 1018 922 1019 923 1020 def TrackSourceWobbleX( sourcename, wobble_pos ): 924 """ general Tracking function 925 """ 926 wp = int(wobble_pos) 927 if wp != 1 and wp != 2: 928 raise ValueError('wobble_pos *must* be 1 or 2') 929 930 if sourcename not in sourcedict: 931 print sourcedict.keys() 932 raise ValueError('sourcename: '+ sourcename +' must be in sourcedict.') 933 934 print 'moving telescope to wobble position ', wp, 'of ', sourcename 935 print '...waiting for DRIVE_CONTROL' 936 print ' to be in state 6: Armed' 937 drive_control.stop() 938 drive_control.wait(6) #Armed 939 print 'DRIVE: ARMED' 940 time.sleep(5.) 941 942 wobble_offset = sourcedict[sourcename]['wobble_offset'] 943 wobble_angle = sourcedict[sourcename]['wobble_angle'+str(wp)] 944 sourcename += '\0' 945 946 last_drive_method = drive_control.track_source 947 last_drive_kwargs = { 'wobble_offset' : wobble_offset, 1021 """ general Tracking function 1022 """ 1023 wp = int(wobble_pos) 1024 if wp != 1 and wp != 2: 1025 raise ValueError('wobble_pos *must* be 1 or 2') 1026 1027 if sourcename not in sourcedict: 1028 print sourcedict.keys() 1029 raise ValueError('sourcename: '+ sourcename +' must be in sourcedict.') 1030 1031 logger.debug('TrackSourceWobbleX: sending drive_control.stop()') 1032 drive_control.stop() 1033 logger.debug('TrackSourceWobbleX: waiting for DRIVE_CONTROL to be "Armed"') 1034 drive_control.wait(6) #Armed 1035 1036 logger.info('moving telescope to wobble position %s of %s' % str(wp), sourcename) 1037 1038 1039 wobble_offset = sourcedict[sourcename]['wobble_offset'] 1040 wobble_angle = sourcedict[sourcename]['wobble_angle'+str(wp)] 1041 sourcename += '\0' 1042 1043 # this is just book keeping. I store the method, which is used 1044 # in this case drive_control.track_source() 1045 # and the arguments, in some global vars .. in order to be able to 1046 # resend the command if necessary. 1047 last_drive_method = drive_control.track_source 1048 last_drive_kwargs = { 'wobble_offset' : wobble_offset, 948 1049 'wobble_angle' : wobble_angle, 949 1050 'source_name' : sourcename } 950 kwa = last_drive_kwargs 951 last_drive_method(kwa['wobble_offset'], kwa['wobble_angle'], kwa['source_name']) 952 953 print '... done' 1051 kwa = last_drive_kwargs 1052 # Here I really send the command 1053 last_drive_method(kwa['wobble_offset'], kwa['wobble_angle'], kwa['source_name']) 1054 1055 logger.debug('TrackSourceWobbleX: waiting for DRIVE_CONTROL to be "Tracking"') 1056 drive_control.wait(8) #Tracking 1057 1058 return True 954 1059 955 1060 def TakeSource( name ): … … 976 1081 StopTracking() 977 1082 978 979 980 981 1083 def set_file_format_to_FITS(): 1084 fad_control.set_file_format(2) 1085 1086 # (Time , Drive, Bias, DAQ, call-before-run) 1087 class RunType(object): 1088 drs_pedestal = (-1, 1000, 'drs-pedestal') 1089 drs_gain = (-1, 1000, 'drs-gain') 1090 drs_time = (-1, 1000, 'drs-time') 1091 drs_time_upshifted = (-1, 1000, 'drs-gain-upshifted') 1092 pedestal = (-1, 1000, 'pedestal') 1093 lightpulser = (-1, 1000, 'light-pulser-ext') 1094 data = (300, -1, 'data') 1095 1096 class Schedule(object): 1097 drs_calib_crab = [ 1098 ( None , ('Crab',1) , 'Off', RunType.drs_pedestal , fad_control.start_drs_calibration ), 1099 ( None , ('Crab',1) , 'Off', RunType.drs_gain , None ), 1100 ( None , ('Crab',1) , 'Off', RunType.drs_pedestal , None ), 1101 ( None , ('Crab',1) , 'Off', RunType.drs_pedestal , set_file_format_to_FITS ), 1102 ( None , ('Crab',1) , 'Off', RunType.drs_time , None ), 1103 ( None , ('Crab',1) , 'Off', RunType.drs_time_upshifted , None ), 1104 ( None , ('Crab',1) , 'Off', RunType.pedestal , fad_control.reset_secondary_drs_baseline ), 1105 ( None , ('Crab',1) , 'Off', RunType.pedestal , None ) 1106 ] 1107 1108 drs_calib_not_moving = [ 1109 ( None , None , 'Off', RunType.drs_pedestal , fad_control.start_drs_calibration ), 1110 ( None , None , 'Off', RunType.drs_gain , None ), 1111 ( None , None , 'Off', RunType.drs_pedestal , None ), 1112 ( None , None , 'Off', RunType.drs_pedestal , set_file_format_to_FITS ), 1113 ( None , None , 'Off', RunType.drs_time , None ), 1114 ( None , None , 'Off', RunType.drs_time_upshifted , None ), 1115 ( None , None , 'Off', RunType.pedestal , fad_control.reset_secondary_drs_baseline ), 1116 ( None , None , 'Off', RunType.pedestal , None ) 1117 ] 1118 1119 data_crab_Wobble_1 = [ 1120 ( None , ('Crab',1) , 'On', RunType.pedestal , None ), 1121 ( None , ('Crab',1) , 'On', RunType.lightpulser , None ), 1122 ( None , ('Crab',1) , 'On', RunType.data , None ), 1123 ( None , ('Crab',1) , 'On', RunType.data , None ), 1124 ( None , ('Crab',1) , 'On', RunType.data , None ), 1125 ( None , ('Crab',1) , 'On', RunType.data , None ), 1126 ] 1127 data_crab_Wobble_2 = [ 1128 ( None , ('Crab',2) , 'On', RunType.pedestal , None ), 1129 ( None , ('Crab',2) , 'On', RunType.lightpulser , None ), 1130 ( None , ('Crab',2) , 'On', RunType.data , None ), 1131 ( None , ('Crab',2) , 'On', RunType.data , None ), 1132 ( None , ('Crab',2) , 'On', RunType.data , None ), 1133 ( None , ('Crab',2) , 'On', RunType.data , None ), 1134 ] 1135 1136 1137 1138 class ScheduledDataTakingThread( threading.Thread ): 1139 """ 1140 1141 """ 1142 def __init__( self , delay = 5): 1143 threading.Thread.__init__(self) 1144 self.stoprequest = threading.Event() 1145 self.warning_state = 'Unknown' 1146 self.state_change = time.time() 1147 self.logger = logging.getLogger('PyDimCtrl.ScheduledDataTakingThread') 1148 1149 self.delay = delay 1150 self.queue = Queue.Queue() 1151 1152 def run(self): 1153 while not self.stoprequest.isSet(): 1154 1155 task = self.queue.get() 1156 1157 start_time = task[0] 1158 drive_task = task[1] 1159 bias_task = task[2] 1160 daq_task = task[3] 1161 pre_action = task[4] 1162 1163 if drive_task is not None: 1164 TrackSourceWobbleX( *drive_task ) 1165 1166 # if start_time is None or start_time > time.gmtime(): 1167 # # do it 1168 # if drive_task is not None: 1169 # TrackSourceWobbleX( *drive_task ) # this blocks until 'Tracking' 1170 # # TODO: 1171 # # spawn a new DriveMonitorThread here and start it. 1172 1173 if bias_task is not None: 1174 if bias_task == 'On': 1175 Make_Bias_On() 1176 else: 1177 Make_Bias_On() 1178 # TODO: 1179 # spawn a new BiasMonitorThread here and start it. 1180 1181 if daq_task is not None: 1182 if pre_action is not None: 1183 pre_action() 1184 MakeReadyForDataTaking() 1185 Take( *daq_task ) 1186 # TODO: 1187 # spawn a new DaqMonitorThread here and start it. 1188 1189 1190 self.queue.task_done() 1191 time.sleep( self.delay ) 1192 1193 def join( self, timeout=None): 1194 self.stoprequest.set() 1195 self.logger.info('was requested to die with timeout=%s' % str(timeout) ) 1196 #super(CheckBiasThread, self).join() 1197 threading.Thread.join(self) 1198 1199 1200 1201 1202 def MakeReadyForDataTaking( delay=1 ): 1203 while fad_control.stn != 4 or ftm_control.stn != 3: # Connected & Idle 1204 logger.info('MakeReadyForDataTaking FTM trigger is still on') 1205 if ftm_control.stn == 4: # Trigger is on 1206 ftm_control.stop_trigger() 1207 1208 logger.warning('MakeReadyForDataTaking FAD: still in WritingData') 1209 if fad_control.stn == 8: # Writing Data 1210 fad_control.close_all_open_files() 1211 1212 logger.warning('MakeReadyForDataTaking FAD: still in one of the Configure(ing) states') 1213 if fad_control.stn in [5,6,7]: # one of the Configure(ing) states 1214 fad_control.reset_configure() 1215 1216 logger.warning('MakeReadyForDataTaking FTM: still in one of the Configure(ing) states') 1217 if ftm_control.stn in [5,6,7]: # one of the Configure(ing) states 1218 ftm_control.reset_configure() 1219 1220 time.sleep(delay) 1221 1222 return True 982 1223 983 1224 def PrintCurrents( x = 1.0): 984 1225 while True: 985 1226 time.sleep( x ) 986 print time.strftime('%d %b %Y %H:%M:%S UTC', time.gmtime()), GetBiasCurrent() 987 1227 GUII = GetBiasCurrent() 1228 interesting = GUII.mean(), GUII.std(), GUII.max(), GUII.min() 1229 print time.strftime('%d %b %Y %H:%M:%S UTC', time.gmtime()), interesting 988 1230 989 1231 … … 1003 1245 return conn 1004 1246 1005 1006 1247 def GetFadBadConnections( good = 0x42 ): 1248 """ returns list of bad FAD IDs 1249 """ 1250 conn = GetFadConnections() 1251 bads = np.where( conn != good) [0] 1252 return bads 1253 1254 1255 def StartUp(): 1256 fad_control.start() 1257 bias_control.reconnect() 1258 bias_control.set_zero_voltage() 1259 while bias_control.stn == 6 : # OverCurrent 1260 bias_control.set_zero_voltage() 1261 bias_control.reset_over_current_status() 1262 1263 ftm_control.reconnect() 1264 1265 number_of_loops = 3 1266 while True: 1267 bad = GetFadBadConnections() 1268 if len(bad) == 0: 1269 break 1270 1271 for b in set( bad/10 ): # set(b/10) contains the crate ids, which have bad FADs 1272 ResetCrate( b ) 1273 1274 number_of_loops -= 1 1275 if not number_of_loops: 1276 print 'StartUp aborted while trying to get the FADs into Connected state ... ' 1277 return False 1278 1279 1280 if not MakeDriveCtrlReady(): 1281 return False 1282 1283 return True 1284 1285 def Shutdown(): 1286 fad_control.stop() 1287 ftm_control.disconnect() 1288 feedback.stop() 1289 bias_control.set_zero_voltage() 1290 1291 1292 1293 def MakeDriveCtrlReady(): 1294 """ Tries to get Drive ctrl from 1295 Disconnected, locked or Error to Armed 1296 after a few tries it gives up and returns False 1297 """ 1298 outer_counter = 3 1299 while drive_control.stn != 6: #Armed 1300 # print 'MakeDriveCtrlReady outer_counter', outer_counter 1301 1302 counter = 3 1303 while drive_control.stn == 1: #Disconnected 1304 # print 'MakeDriveCtrlReady in while 1, counter:', counter 1305 drive_control.reconnect() 1306 time.sleep(0.5) 1307 counter -= 1 1308 if not counter: 1309 print 'count not connect drive control to cosy ... please check if cosy is running' 1310 return False 1311 1312 counter = 3 1313 while drive_control.stn == 3: # Locked 1314 # print 'MakeDriveCtrlReady in while 2, counter:', counter 1315 drive_control.unlock() 1316 time.sleep(0.5) 1317 counter -= 1 1318 if not counter: 1319 print 'could not unlock drive control WTF?' 1320 return False 1321 1322 counter = 3 1323 while drive_control.stn == 256: # ERROR 1324 # print 'MakeDriveCtrlReady in while 3, counter:', counter 1325 drive_control.stop() 1326 time.sleep(0.5) 1327 counter -= 1 1328 if not counter: 1329 print 'could not unlock drive control WTF?' 1330 return False 1331 1332 outer_counter -= 1 1333 if not outer_counter: 1334 print 'ERROR while trying to get Drive control ready' 1335 return False 1336 1337 return True 1338 1339 feedback_calibration_done = None # Bool... 1340 1341 def Make_Bias_Off(): 1342 1343 bias_control.set_zero_voltage() 1344 bias_control.wait(7) 1345 1346 1347 def Make_Bias_On(): 1348 """ Tries to get the Bias, and Feedback into a defined safe Off state 1349 While beeing as ready as possible to go into On state 1350 """ 1351 global feedback_calibration_done 1352 # Feedback states: 1353 #List of available states: 1354 #-[-1]: NotReady (State machine not ready, events are ignored.) 1355 #-[0]: Ready (State machine ready to receive events.) 1356 #-[1]: DimNetworkNotAvailable (The Dim DNS is not reachable.) 1357 #-[2]: Disconnected (The Dim DNS is reachable, but the required subsystems are not available.) 1358 #-[3]: Connecting (Only biasctrl is available and connected with its hardware.) 1359 #-[4]: ConnectedFSC (biasctrl and fscctrl are available and connected with their hardware.) 1360 #-[5]: ConnectedFAD (biasctrl and fadctrl are available and connected with their hardware.) 1361 #-[6]: Connected (biasctrl, fadctrl and fscctrl are available and connected with their hardware.) 1362 #-[7]: TempCtrlIdle (Temperature control activated, but voltage output disabled.) 1363 #-[8]: FeedbackIdle (Feedback control activated, but voltage output disabled.) 1364 #-[9]: CurrentCtrlIdle (Current control activated, but voltage output disabled.) 1365 #-[10]: TempControl (Temperature control activated and voltage output enabled.) 1366 #-[11]: FeedbackControl (Feedback control activated and voltage output enabled.) 1367 #-[12]: CurrentControl (Current/Temp control activated and voltage output enabled.) 1368 #-[13]: Calibrating (Calibrating current offsets.) 1369 #-[256]: ERROR (Common error state.) 1370 #-[65535]: FATAL (A fatal error occured, the eventloop is stopped.) 1371 1372 1373 while not ( (feedback.stn == 12) and 1374 (bias_control.stn == 9) and 1375 (np.array(bias_control.voltage()[0:320]).mean() > 65.) ): 1376 1377 # for security 1378 feedback.enable_output(0) 1379 1380 # try to get bias_control into state: VoltageOn 1381 while not bias_control.stn == 9: 1382 1383 if bias_control.stn == 1: #Disconnected 1384 bias_control.reconnect() 1385 if bias_control.stn == 2: #Connecting 1386 time.sleep(1) 1387 if bias_control.stn == 3: #Initializing 1388 time.sleep(1) 1389 if bias_control.stn == 4: #Connected 1390 # this seems never to happen ... 1391 time.sleep(1) 1392 #bias_control.set_global_dac(1) 1393 if bias_control.stn == 5: #Ramping 1394 time.sleep(1) 1395 if bias_control.stn == 6: #OverCurrent 1396 bias_control.set_zero_voltage() 1397 time.sleep(1) 1398 bias_control.reset_over_current_status() 1399 if bias_control.stn == 7: #VoltageOff 1400 bias_control.set_global_dac(1) 1401 if bias_control.stn == 8: #NotReferenced 1402 bias_control.set_zero_voltage() 1403 if bias_control.stn == 9: #VoltageOn 1404 pass 1405 if bias_control.stn > 9: 1406 print "BIAS control is in strange status... don't know what to do" 1407 time.sleep(1) 1408 time.sleep(1) 1409 1410 1411 # Try to get Feedback into CurrentControl 1412 while not (feedback.stn == 12): 1413 1414 if feedback.stn < 6: # not properly connected. 1415 # State 6 is 'Connected' but this normaly hardly shows up 1416 # Its either voltageOff or any other meaningful state... 1417 print "FEEDBACK not properly connected..." 1418 time.sleep(1) 1419 1420 if feedback.stn == 13: #Calibrating 1421 time.sleep(1) 1422 continue 1423 1424 if not feedback_calibration_done: 1425 if feedback.calibration() is None: 1426 print "FEEDBACK has not CURRENT CALIBRATION" 1427 print "TRYING TO CALIBRATE" 1428 feedback.calibrate_currents() 1429 time.sleep(0.5) 1430 continue 1431 else: 1432 feedback_calibration_done = True 1433 1434 if feedback.stn == 6: #Connected 1435 feedback.start_current_control(0.0) 1436 1437 if feedback.stn in [7,8]: #TempCtrlIdle , FeedbackIdle 1438 feedback.stop() 1439 time.sleep(0.5) 1440 feedback.start_current_control(0.0) 1441 1442 if feedback.stn == 9: #CurrentCtrlIdle 1443 feedback.enable_output(1) 1444 1445 if feedback.stn in [10,11]: #TempControl, FeedbackControl 1446 feedback.stop() 1447 time.sleep(0.5) 1448 feedback.start_current_control(0.0) 1449 1450 if feedback.stn == 12: # This is where we want ot be 1451 pass 1452 1453 1454 time.sleep(1) 1455 # Bias States 1456 #List of available states: 1457 #-[-1]: NotReady (State machine not ready, events are ignored.) 1458 #-[0]: Ready (State machine ready to receive events.) 1459 #-[1]: Disconnected (Bias-power supply not connected via USB.) 1460 #-[2]: Connecting (Trying to establish USB connection to bias-power supply.) 1461 #-[3]: Initializing (USB connection to bias-power supply established, synchronizing USB stream.) 1462 #-[4]: Connected (USB connection to bias-power supply established.) 1463 #-[5]: Ramping (Voltage ramping in progress.) 1464 #-[6]: OverCurrent (At least one channel is in over current state.) 1465 #-[7]: VoltageOff (All voltages are supposed to be switched off.) 1466 #-[8]: NotReferenced (Internal reference voltage does not match last sent voltage.) 1467 #-[9]: VoltageOn (At least one voltage is switched on and all are at reference.) 1468 #-[10]: ExpertMode (Special (risky!) mode to directly send command to the bias-power supply.) 1469 #-[256]: ERROR (Common error state.) 1470 #-[65535]: FATAL (A fatal error occured, the eventloop is stopped.) 1471 1472 1473 class CheckBiasThread( threading.Thread ): 1474 """ Thread, which continously monitors the Bias_Control status every 1475 *delay* seconds. 1476 in case of too high currents it will ... 1477 .... do nothing :-) yet. 1478 So far it will just change its internal state from 'Normal' 1479 to 'PreWarning' or 'Serious'. 1480 If the currents remain "high" for more than 1481 *serious_action_after* seconds. some action would be taken. 1482 I our case, just a WARNING will be logged. 1483 1484 The caller thread should check the *warning_state* from outside this 1485 thread and take apropriate actions, when 'PreWarning' is reached... 1486 1487 1488 """ 1489 def __init__( self , delay=5, serious_action_after = 60 ): 1490 #super(CheckBiasThread, self).__init__() 1491 threading.Thread.__init__(self) 1492 self.stoprequest = threading.Event() 1493 self.warning_state = 'Unknown' 1494 self.state_change = time.time() 1495 self.delay = delay 1496 self.serious_action_after = serious_action_after 1497 self.logger = logging.getLogger('PyDimCtrl.CheckBiasThread') 1498 1499 def run(self): 1500 while not self.stoprequest.isSet(): 1501 1502 if (self.warning_state == 'Serious' and 1503 time.time()-self.state_change > self.serious_action_after): 1504 # Remergency Ramp Down 1505 self.logger.info('At this moment, I would ramp down the voltage') 1506 self.logger.warning('G-APD currents are too high, since %d seconds' % self.serious_action_after) 1507 self.logger.warning('Emergency voltage shutdown [not yet implemented]') 1508 1509 currents = GetPixelCurrents() 1510 if ( (np.median(currents) > 70) or (currents.max() > 90) ): 1511 if self.warning_state != 'Serious': 1512 self.logger.info('trasit into Serious Warning') 1513 self.warning_state = 'Serious' 1514 self.state_change = time.time() 1515 1516 elif ( (np.median(currents) > 60) or (currents.max() > 80) ): 1517 if self.warning_state != 'PreWarning': 1518 self.logger.info('transit into Pre Warning') 1519 self.warning_state = 'PreWarning' 1520 self.state_change = time.time() 1521 1522 elif ( (np.median(currents) < 60) or (currents.max() < 80) ): 1523 if self.warning_state != 'Normal': 1524 self.logger.info('transit into Normal Situation') 1525 self.warning_state = 'Normal' 1526 self.state_change = time.time() 1527 1528 if bias_control.stn == 6: #Overcurrent 1529 if self.warning_state != 'OverCurrent': 1530 self.logger.warning('trasit into Overcurrent State during data Taking') 1531 self.warning_state = 'OverCurrent' 1532 self.state_change = time.time() 1533 1534 if bias_control.stn == 1: #Disconnected 1535 if self.warning_state != 'Disconnected': 1536 self.logger.warning('trasit into Disconnected state during data Taking') 1537 self.warning_state = 'Disconnected' 1538 self.state_change = time.time() 1539 1540 1541 1542 time.sleep( self.delay ) 1543 1544 def join( self, timeout=None): 1545 self.stoprequest.set() 1546 1547 self.logger.info('was requested to die with timeout=%s' % str(timeout) ) 1548 #super(CheckBiasThread, self).join() 1549 threading.Thread.join(self) 1550 1551 1552 class CheckDriveThread( threading.Thread ): 1553 """ Thread, which continously monitors the Drive_Control status every 1554 *delay* seconds. 1555 in case Drive_Control goes into Error State it will 1556 send: 1557 * STOP 1558 * and then resend the last tracking command 1559 1560 In case sending STOP is not bringing the Drive_Control back to 1561 state 'Armed' it will try again. Until the *try_counter* is zero. 1562 Then it will totally Freak out. 1563 1564 .... does nothing really! :-) yet. 1565 1566 """ 1567 def __init__( self , try_counter = 5, timeout = 30, delay=5 ): 1568 threading.Thread.__init__(self) 1569 self.stoprequest = threading.Event() 1570 1571 self.error_counter = 0 1572 self.try_counter = try_counter 1573 self.timeout = timeout 1574 self.delay = delay 1575 1576 self.warning_state = 'Unknown' 1577 self.state_change = time.time() 1578 1579 self.logger = logging.getLogger('PyDimCtrl.CheckDriveThread') 1580 1581 def run(self): 1582 while not self.stoprequest.isSet(): 1583 1584 if drive_control.stn == 256: #Error 1585 self.error_counter += 1 1586 self.state_change = time.time() 1587 self.warning_state = 'ErrorFound' 1588 self.logger.info('found Error State ... starting to react on it.') 1589 self.logger.warning(' Error State ') 1590 1591 start_of_Error_reaction = time.time() 1592 while not drive.stn == 8: #Tracking 1593 if drive_control.stn == 256: #Error 1594 if try_counter: 1595 self.logger.info('sending STOP') 1596 drive_control.stop() 1597 try_counter -= 1 1598 time.sleep(1) 1599 1600 elif drive_control.stn == 6: #Armed 1601 kwa = last_drive_kwargs 1602 self.logger.info('resending last tracking command') 1603 last_drive_method(kwa['wobble_offset'], 1604 kwa['wobble_angle'], 1605 kwa['source_name']) 1606 time.sleep(2) 1607 else: 1608 self.logger.error('found Error, but now neither Error state nor Armed state?!') 1609 self.logger.error('what should I do?') 1610 self.logger.error('thread aborting') 1611 self.warning_state = 'Critical' 1612 self.stoprequest.set() 1613 threading.Thread.join(self) 1614 1615 if time.time() - start_of_Error_reaction > self.timeout: 1616 self.logger.error('timed out while trying to react on Drive Control Error') 1617 self.logger.error('what should I do?') 1618 self.logger.error('thread aborting') 1619 self.warning_state = 'Critical' 1620 #self.stoprequest.set() 1621 #threading.Thread.join(self) 1622 self.join() 1623 1624 else: 1625 if self.warning_state != 'Normal': 1626 self.logger.info('transit into Normal Situation') 1627 self.warning_state = 'Normal' 1628 self.state_change = time.time() 1629 1630 time.sleep( self.delay ) 1631 1632 def join( self, timeout=None): 1633 self.stoprequest.set() 1634 self.logger.info('was requested to die with timeout=%s' % str(timeout)) 1635 threading.Thread.join(self) 1636 1637 1638 class BiasThread(threading.Thread): 1639 """ A worker thread that takes directory names from a queue, finds all 1640 files in them recursively and reports the result. 1641 1642 Input is done by setting the *requested_state*: 1643 ['On', 'Off'] 1644 Output is done by setting the *readyness*: 1645 ['Ready', 'NotYet', 'CantDoIt'] 1646 1647 Ask the thread to stop by calling its join() method. 1648 """ 1649 requests = ['On', 'Off'] 1650 readynesses = ['Ready', 'NotYet', 'CantDoIt'] 1651 requested_state = None 1652 readyness = 'NotYet' 1653 1654 def __init__(self, start_state = 'Off'): 1655 super(BiasThread, self).__init__() 1656 BiasThread.requested_state = start_state 1657 self.stoprequest = threading.Event() 1658 1659 def run(self): 1660 # As long as we weren't asked to stop, try to find out, if we are in 1661 # the requested state, if not, try to reach the state... 1662 while not self.stoprequest.isSet(): 1663 1664 if not self.InRequestedState(): 1665 print 'not in Requested State', BiasThread.requested_state 1666 BiasThread.readyness = 'NotYet' 1667 1668 try: 1669 dirname = self.dir_q.get(True, 0.05) 1670 filenames = list(self._files_in_dir(dirname)) 1671 self.result_q.put((self.name, dirname, filenames)) 1672 except Queue.Empty: 1673 continue 1674 1675 def join(self, timeout=None): 1676 self.stoprequest.set() 1677 super(BiasThread, self).join(timeout) 1678 1679 def InRequestedState(): 1680 """ 1681 """ 1682 if BiasThread.requested_state == 'On': 1683 pass 1684 elif BiasThread.requested_state == 'Off': 1685 pass 1686 else: # Houston we have a problem! 1687 pass 1688 1689 1690 1691 1692 class CheckDaqThread( threading.Thread ): 1693 """ Thread, which continously monitors the Rate 1694 1695 in case the rate is < 1Hz --> Bing bing 1696 1697 """ 1698 def __init__( self , delay=5 ): 1699 threading.Thread.__init__(self) 1700 self.stoprequest = threading.Event() 1701 1702 self.delay = delay 1703 1704 self.warning_state = 'Unknown' 1705 self.state_change = time.time() 1706 1707 self.logger = logging.getLogger('PyDimCtrl.CheckDaqThread') 1708 1709 def run(self): 1710 while not self.stoprequest.isSet(): 1711 1712 rate = ftm_control.trigger_rates()[3] 1713 if rate < 1: 1714 if self.warning_state != 'SmallRate': 1715 self.logger.warning('SmallRate detected!') 1716 self.warning_state = 'SmallRate' 1717 self.state_change = time.time() 1718 else: 1719 if self.warning_state != 'Normal': 1720 self.logger.info('transit to Normal') 1721 self.warning_state = 'Normal' 1722 self.state_change = time.time() 1723 1724 time.sleep( self.delay ) 1725 1726 def join( self, timeout=None): 1727 self.stoprequest.set() 1728 self.logger.info('was requested to die with timeout=%s' % str(timeout)) 1729 threading.Thread.join(self) 1730 1731 1732 1733 def off(): 1734 for m in monis: 1735 m.join() 1736 1737 monis = [] 1007 1738 if __name__ == '__main__': 1008 1739 print 'Welcome to PyDimCtrl' … … 1017 1748 print 1018 1749 1019 1750 #bm = CheckBiasThread() 1751 #dm = CheckDriveThread() 1752 #rm = CheckDaqThread() 1753 #monis = [bm, dm, rm] 1754 # bm.start() 1755 # dm.start() 1756 # rm.start() 1757 #print 1758 #print 'monis created'
Note:
See TracChangeset
for help on using the changeset viewer.