def __init__(self): self.graphics = Graphics(matrix_width, matrix_height) self.serialPort = None self.reset()
class LHC(object): def __init__(self): self.graphics = Graphics(matrix_width, matrix_height) self.serialPort = None self.reset() def reset(self): self.bot_pos = BOT_BEGIN self.duo_pos = DUO_BEGIN self.lin_pos = LIN_BEGIN self.sps_pos = SPS_BEGIN self.lhc_pos = LHC_BEGIN # count number of produced bunches self.sps_bcnt = 0 self.lhc_bcnt = 0 self.bot_done = False self.duo_done = False self.lin_done = False self.sps_done = False self.lhc_done = False self.tfl_done = False self.tfr_done = False self.debug = False self.graphics.fill(BLACK) # self.sqrtable = list(repeat(100,parabola, 1, 100)) # self.sqrtable = list([x*x/2 for x in xrange (170)]) self.lin_bunches = list() self.sps_bunches = list() self.tfl_bunches = list() self.tfr_bunches = list() self.lhc_bunches = [[] for k in range(2)] self.collisions = list() self.alice_colcnt = 0 self.restart = True if self.serialPort: self.serialPort.flushInput() self.osc_atlas = liblo.Address("mc-im-pc5", 7777) self.osc_alice = liblo.Address("mc-im-pc6", 7777) self.osc_cms = liblo.Address("mc-im-pc7", 7777) self.osc_lhcb = liblo.Address("mc-im-pc8", 7777) def checkCollision(self, b1x, b1y, other_dir): global g_atlas_col global g_alice_col global g_cms_col global g_lhcb_col global g_last_collision collision = False # if global_i > g_last_collision + 250: timePassed = True # else: # timePassed = False for b2 in self.lhc_bunches[other_dir]: if b1x in range(b2.x - 1, b2.x + 1) and b1y == b2.y: if b1x in ATLASr and g_atlas_col < 10000 and timePassed: g_atlas_col += 1 g_last_collision = global_i self.collisions.append([ATLAS, b1y, 30]) try: liblo.send(self.osc_atlas, "/collision", ("i", 1)) except: print("could not send ATALS trigger") return True if b1x in ALICEr and g_alice_col < 10000 and timePassed: self.alice_colcnt += 1 # every third time only if self.alice_colcnt % 4 == 0: g_alice_col += 1 g_last_collision = global_i self.collisions.append([ALICE, b1y, 30]) try: liblo.send(self.osc_alice, "/collision", ("i", 1)) except: print("could not send ALICE trigger") return True if b1x in CMSr and g_cms_col < 100000 and timePassed: g_cms_col += 1 g_last_collision = global_i self.collisions.append([CMS, b1y, 30]) try: liblo.send(self.osc_cms, "/collision", ("i", 1)) except: print("could not send CMS trigger") return True if b1x in LHCbr and g_lhcb_col < 100000 and timePassed: g_lhcb_col += 1 g_last_collision = global_i self.collisions.append([LHCb, b1y, 30]) try: liblo.send(self.osc_lhcb, "/collision", ("i", 1)) except: print("could not send LHCb trigger") return True return collision def updateCollisions(self): global g_last_collision global global_i # col_pat=[[255,255,255], [50,50,50], [0,0,0], [255,255,255], [50,50,50],[255,0,0],[0,255,0],[0,0,255],[0,255,255]] col_pat = [ WHITE, (50, 50, 50), (0, 0, 0), (255, 255, 255), (50, 50, 50), (255, 0, 0), (0, 255, 0), (0, 0, 255), (0, 255, 255), ] # for testing # self.collisions.append([ATLAS, 3, 100]) # g_last_collision = 1 if g_last_collision > 0: del_collisions = list() for index, collision in enumerate(self.collisions): # if global_i%3 == 0: # color = WHITE # elif global_i%3 == 1: # color = (50,50,50) # elif global_i%3 == 2: # color = BLACK color = col_pat[global_i % len(col_pat)] # border = map(sub,color,(200,200,200)) # for i,col in enumerate(border): # if col < 0: # col = 1 # border[i]=col # border = tuple(border) self.graphics.drawPixel(collision[0] - 1, collision[1], color) self.graphics.drawPixel(collision[0], collision[1], color) self.graphics.drawPixel(collision[0] + 1, collision[1], color) # decrement life time counter collision[2] -= 1 if collision[2] < 0: del_collisions.append(index) # cleanup for index in sorted(del_collisions, reverse=True): del self.collisions[index] def animateSrtripe(self, pattern, x, min_x, max_x, acc, y): global global_i for pixel in range(min_x, max_x): # pixel = math.floor(pixel * acc) # pixel = int(pixel) # pixel = min(pixel, max_x) if x < max_x and x < pixel: color = BLACK else: color = pattern[(pixel - (global_i / 5)) % len(pattern)] self.graphics.drawPixel(pixel, y, color) def updateBottle(self): self.animateSrtripe(bot_pat, self.bot_pos, BOT_BEGIN, BOT_END, 0.5, 1) self.bot_pos += 3 if self.bot_pos >= BOT_END: self.bot_done = True if self.debug: print(self.bot_pos) def updateDuoplasmatron(self): if self.bot_done: self.animateSrtripe(duo_pat, self.duo_pos, DUO_BEGIN, DUO_END, 1, 1) self.duo_pos += 1 if self.duo_pos >= DUO_END: self.duo_done = True if self.debug: print(self.duo_pos) def updateLINAC(self, config, pattern): global global_i if self.duo_done: del_bunches = list() for index, bnch in enumerate(self.lin_bunches): if bnch.cycles == 0: # print('ALIVE') if bnch.x > 168: bnch.mode = LONG else: bnch.mode = SHORT bnch.draw() bnch.travel() else: # print("creating SPS bunches") self.lin_done = True new_bunch = Bunch(self.graphics, sps_conf, sps_pat, 1.0) self.sps_bunches.append(new_bunch) # new_bunch = Bunch(self.graphics, sps_conf, sps_pat,1,1) # self.sps_bunches.append(new_bunch) del_bunches.append(index) # print ("before bunches", len(self.bunches)) for index in sorted(del_bunches, reverse=True): del self.lin_bunches[index] # print ("after bunches", len(self.bunches)) if global_i % 8 == 0: # accelerate protons in linac # if global_i == 0: new_bunch = Bunch(self.graphics, config, pattern, 1.05) self.lin_bunches.append(new_bunch) # print('NEW BUNCH', global_i % 10) # self.lin_pos += 1 # if self.lin_pos >= LIN_END: # self.lin_done = True # self.lin_pos = 0 if self.debug: print(self.lin_pos) def updateSPS(self, config, pattern): global global_i if self.lin_done: del_bunches = list() for index, bnch in enumerate(self.sps_bunches): if bnch.cycles == 0: # print('ALIVE') if bnch.x > 4: bnch.mode = LONG else: bnch.mode = SHORT bnch.draw() bnch.travel() # print(bnch.x) if self.sps_bcnt >= 3 * 4 and self.sps_bcnt < 3 * 11: if global_i % 3 == 0: if bnch.x == 20: self.sps_done = True # print("TF right") new_bunch = Bunch(self.graphics, tf_conf_right, lhc_pat_cw, 1.0) self.tfr_bunches.append(new_bunch) elif bnch.x == 38: # print("TF left") self.sps_done = True # duplicate new_bunch = Bunch(self.graphics, tf_conf_left, lhc_pat_cw, 1.0) self.tfl_bunches.append(new_bunch) else: del_bunches.append(index) self.sps_bcnt += 1 # print("inc",self.sps_cycle) # print ("before bunches", len(self.bunches)) for index in sorted(del_bunches, reverse=True): del self.sps_bunches[index] if self.debug: print(self.sps_pos) def updateTF(self, config, pattern, line): global global_i if self.sps_done: del_bunches = list() if line == TFL: bunches = self.tfl_bunches else: bunches = self.tfr_bunches for index, bnch in enumerate(bunches): if bnch.cycles == 0: # print('ALIVE') bnch.mode = LONG bnch.draw() bnch.travel() else: if line == TFL: # print("tfl done") self.tfl_done = True new_bunch = Bunch(self.graphics, lhc_conf[CW], lhc_pat_cw, 1.0, CW) self.lhc_bunches[CW].append(new_bunch) else: self.tfr_done = True new_bunch = Bunch(self.graphics, lhc_conf[CCW], lhc_pat_ccw, 1.0, CCW) self.lhc_bunches[CCW].append(new_bunch) del_bunches.append(index) for index in sorted(del_bunches, reverse=True): del bunches[index] def updateLHC(self, config, pattern, direction): global global_i if (self.tfl_done == True and direction == CW) or (self.tfr_done == True and direction == CCW): del_bunches = list() for index, bnch in enumerate(self.lhc_bunches[direction]): if bnch.cycles == 0: # print('ALIVE') bnch.mode = LONG if self.lhc_pos > 1 * 2 * LHC_SIZE and ( (direction == CW and self.checkCollision(bnch.x, bnch.y, CCW)) or (direction == CCW and self.checkCollision(bnch.x, bnch.y, CW)) ): if self.debug: print("collide", bnch.x, bnch.y) # bnch.cycles += 1 # no deletion of bunches as only very few partciles collide per turn # del_bunches.append(index) # del_bunches.append(index-1) else: bnch.draw() bnch.travel() else: new_bunch = Bunch(self.graphics, lhc_conf[direction], pattern, 1.0, direction) self.lhc_bunches[direction].append(new_bunch) del_bunches.append(index) for index in sorted(del_bunches, reverse=True): del self.lhc_bunches[direction][index] # print(self.lhc_pos) if self.lhc_pos > 10 * 2 * (LHC_SIZE): # sys.exit(2) # return 0 self.lhc_done = True else: self.lhc_pos += 1 return 1 def generate(self): global global_i global g_atlas_col global g_alice_col global g_cms_col global g_lhcb_col global g_last_collision if self.restart: global_i = 0 g_atlas_col = 0 g_alice_col = 0 g_cms_col = 0 g_lhcb_col = 0 g_last_collision = 0 self.reset() while self.serialPort == None: try: print("-> trying to open serial port") self.serialPort = serial.Serial("/dev/cu.usbmodem1411", 115200, timeout=None) except: # print('serial port not valid') self.serialPort = None time.sleep(1) print("-> Ready, touch the bottle...") self.serialPort.flushInput() self.serialPort.read(1) self.serialPort.close() self.serialPort = None # print("Press any key to continue...") # os.system('read -s -n 1') self.restart = False print("{:%Y-%b-%d %H:%M:%S} -> starting LED strip animation".format(datetime.datetime.now())) self.graphics.fill(BLACK) # self.bot_done = True # self.duo_done = True self.updateBottle() self.updateDuoplasmatron() self.updateLINAC(lin_conf, lin_pat) self.updateSPS(sps_conf, sps_pat) self.updateTF(lhc_conf, lhc_pat_cw, TFL) self.updateTF(lhc_conf, lhc_pat_cw, TFR) self.updateLHC(lhc_conf, lhc_pat_cw, CW) self.updateLHC(lhc_conf, lhc_pat_ccw, CCW) self.updateCollisions() if self.lhc_done: # reset print("-> LED strip animation ended") self.graphics.fill(BLACK) self.restart = True global_i += 1 return self.graphics.getSurface()