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