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