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