class PhaseScan_Runner(Runnable): def __init__(self,scl_long_tuneup_controller, run_to_end = true): self.scl_long_tuneup_controller = scl_long_tuneup_controller self.run_to_end = run_to_end self.harmonicsAnalyzer = HarmonicsAnalyzer(2) #--- fake scan boolean variable scl_long_tuneup_phase_scan_controller = self.scl_long_tuneup_controller.scl_long_tuneup_phase_scan_controller set_phase_shift_panel = scl_long_tuneup_phase_scan_controller.set_phase_shift_panel self.fake_scan = set_phase_shift_panel.scanSim_RadioButton.isSelected() self.useTrigger = set_phase_shift_panel.beamTrigger_RadioButton.isSelected() self.keepCavPhases = set_phase_shift_panel.keepLiveCavPhases_RadioButton.isSelected() self.wrapPhases = set_phase_shift_panel.wrapPhases_RadioButton.isSelected() def run(self): messageTextField = self.scl_long_tuneup_controller.getMessageTextField() if(messageTextField != null): messageTextField.setText("") scl_long_tuneup_phase_scan_controller = self.scl_long_tuneup_controller.scl_long_tuneup_phase_scan_controller scan_state_controller = scl_long_tuneup_phase_scan_controller.scan_state_controller cavs_table = scl_long_tuneup_phase_scan_controller.cavs_table cav_wrappers = self.scl_long_tuneup_controller.cav_wrappers n_cavs = len(cav_wrappers) phase_step = scl_long_tuneup_phase_scan_controller.start_stop_scan_panel.phase_step_text.getValue() time_wait = scl_long_tuneup_phase_scan_controller.set_phase_shift_panel.time_wait_text.getValue() scan_status_text = scl_long_tuneup_phase_scan_controller.start_stop_scan_panel.scan_status_text scl_long_tuneup_init_controller = self.scl_long_tuneup_controller.scl_long_tuneup_init_controller if(not scl_long_tuneup_init_controller.allPairsSet()): if(messageTextField != null): messageTextField.setText("You should Initialize the scan first! Go to the Init tab!") return scl_long_tuneup_init_controller.connectAllBPMs() beamTrigger = self.scl_long_tuneup_controller.beamTrigger bpmBatchReader = self.scl_long_tuneup_controller.bpmBatchReader bpm_amp_min_limit = scl_long_tuneup_phase_scan_controller.post_scan_panel.amp_limit_text.getValue() #------------------------------- CA START # ?????? For live CA if(beamTrigger == null): if(messageTextField != null): messageTextField.setText("You should Initialize the scan first! Go to the Init tab!") return else: beamTrigger.setFakeScan(self.fake_scan) beamTrigger.setUseTrigger(self.useTrigger) beamTrigger.setSleepTime(time_wait) beamTrigger.scan_state_controller = scan_state_controller bpmBatchReader.setBeamTrigger(beamTrigger) #------------------------------- CA END #---------start deal with selected cavities cav_selected_inds = cavs_table.getSelectedRows() if(len(cav_selected_inds) < 1 or cav_selected_inds[0] < 0): if(messageTextField != null): messageTextField.setText("Select one or more cavities to start Phase Scan!") beamTrigger.setFakeScan(false) return # these are the table model indexes cav_wrapper = null start_ind = cav_selected_inds[0] last_ind = cav_selected_inds[len(cav_selected_inds)-1] if(self.run_to_end): last_ind = n_cavs #----- blank and clean scan data for all downstream cavities cav_wrapper = self.scl_long_tuneup_controller.cav0_wrapper if(start_ind != 0): cav_wrapper = cav_wrappers[start_ind-1] cav_wrapper.clean() for cav_table_ind in range(start_ind+1,n_cavs+1): cav_wrapper = cav_wrappers[cav_table_ind-1] if(cav_wrapper.isGood): # ?????? should be tested with CA if(not self.fake_scan): cav_wrapper.setBlankBeam(true) cav_wrapper.clean() cavs_table.getModel().fireTableDataChanged() #-------start loop over cavities in the table result = true time_start = time.time() n_total = last_ind - start_ind + 1 n_count = 0 for cav_table_ind in range(start_ind,last_ind+1): cavs_table.setRowSelectionInterval(cav_table_ind,cav_table_ind) cav_wrapper = self.scl_long_tuneup_controller.cav0_wrapper if(cav_table_ind != 0): cav_wrapper = cav_wrappers[cav_table_ind-1] if(not cav_wrapper.isGood): continue if(cav_table_ind != 0): # ?????? should be tested with CA if(not self.fake_scan): cav_wrapper.setBlankBeam(false) txt = "Scan is running! Cavity="+cav_wrapper.alias if(start_ind != last_ind): txt = txt + " to Cavity="+cav_wrappers[last_ind-1].alias if(n_count > 1): run_time = time.time() - time_start run_time_sec = int(run_time % 60) run_time_min = int(run_time/60.) eat_time = ((run_time/n_count)*(n_total - n_count)) eat_time_sec = int(eat_time % 60) eat_time_min = int(eat_time/60.) txt = txt + " ETA= %3d min %2d sec "%(eat_time_min,eat_time_sec) txt = txt + " Elapse= %3d min %2d sec "%(run_time_min,run_time_sec) scan_status_text.setText(txt) if(scan_state_controller.getShouldStop()): break cav_phase = -180. while(cav_phase <= 180.): #debug #print "debug cav=",cav_wrapper.alias," phase=",cav_phase #--------set cavity phase if(cav_table_ind != 0): # ?????? should be tested with CA if(not self.fake_scan): cav_wrapper.cav.setCavPhase(cav_phase) if(cav_wrapper == self.scl_long_tuneup_controller.cav0_wrapper): scan_status_text.setText("Scan running cavity= "+cav_wrapper.alias+" phase="+str(cav_phase)) if(scan_state_controller.getShouldStop()): break time.sleep(time_wait) if(scan_state_controller.getShouldStop()): break # ?????? For live CA result = false if(not self.fake_scan): result = bpmBatchReader.makePhaseScanStep(cav_phase,cav_wrapper,bpm_amp_min_limit) else: result = self.fakeMakePhaseScanStep(cav_phase,cav_wrapper) if(scan_state_controller.getShouldStop()): break if(result == false): scan_status_text.setText("Scan stopped. Could not get BPM data. Please check!") if(messageTextField != null): messageTextField.setText("") beamTrigger.setFakeScan(false) return if(cav_table_ind != 0): cav_wrapper.addScanPointToPhaseDiffData() cav_phase += phase_step #----end of phase loop if(scan_state_controller.getShouldStop()): break #set up the Cavity phase according to scan if(cav_table_ind != 0): res_phase_set = self.setUpCavityPhase(cav_wrapper) time.sleep(time_wait) if(not res_phase_set): scan_status_text.setText("Scan stopped! Bad scan! Cannot set up phase for cavity="+cav_wrapper.alias) beamTrigger.setFakeScan(false) return cav_wrapper.isMeasured = true cavs_table.getModel().fireTableDataChanged() n_count += 1 #------end of cavities loop txt = "" if(cav_wrapper != null): txt = " The last cavity was "+cav_wrapper.alias+" ." run_time = time.time() - time_start run_time_sec = int(run_time % 60) run_time_min = int(run_time/60.) txt = txt + " Total time= %3d min %2d sec "%(run_time_min,run_time_sec) if(scan_state_controller.getShouldStop()): scan_status_text.setText("Scan was interrupted!"+txt) else: scan_status_text.setText("Scan finished!"+txt) #restore the beam trigger fake scan state beamTrigger.setFakeScan(false) def setUpCavityPhase(self,cav_wrapper): #--- wrap all BPMs phase scans at once if(self.wrapPhases): res_phase_wrap = self.allBPMs_PhaseWrapper(cav_wrapper) if(not res_phase_wrap): return false max_bad_points_count = 2 gd = cav_wrapper.phaseDiffPlot gdTh = cav_wrapper.phaseDiffPlotTh gdTh.removeAllPoints() if(gd.getNumbOfPoints() < 8): return false err = self.harmonicsAnalyzer.analyzeData(gd) harm_function = self.harmonicsAnalyzer.getHrmonicsFunction() #-----remove bad points bad_points_count = 0 bad_index = 1 while(bad_index >= 0): bad_index = -1 for i in range(gd.getNumbOfPoints()): phase = gd.getX(i) y_appr = harm_function.getValue(phase) y = gd.getY(i) if(math.fabs(y-y_appr) > 3.0*err): bad_index = i bad_points_count += 1 break if(bad_index >= 0): gd.removePoint(bad_index) bpm_wrappers = cav_wrapper.bpm_wrappers for bpm_wrapper in bpm_wrappers: if(cav_wrapper.bpm_amp_phase_dict.has_key(bpm_wrapper)): (graphDataAmp,graphDataPhase) = cav_wrapper.bpm_amp_phase_dict[bpm_wrapper] graphDataAmp.removePoint(bad_index) graphDataPhase.removePoint(bad_index) # we should stop if we have too many bad points if(bad_points_count > max_bad_points_count): return false if(bad_points_count > 0): err = self.harmonicsAnalyzer.analyzeData(gd) harm_function = self.harmonicsAnalyzer.getHrmonicsFunction() #----find a new cavity phase min_phase = self.harmonicsAnalyzer.getPositionOfMin() new_phase = cav_wrapper.initLivePhase if(self.keepCavPhases): cav_wrapper.scanPhaseShift = makePhaseNear(new_phase - min_phase,0.) else: new_phase = makePhaseNear(min_phase + cav_wrapper.scanPhaseShift,0.) # ?????? should be tested with CA cav_wrapper.livePhase = new_phase if(not self.fake_scan): cav_wrapper.cav.setCavPhase(cav_wrapper.livePhase) cav_wrapper.livePhase = new_phase cav_wrapper.phase_scan_harm_amp = harm_function.getParamArr()[1] cav_wrapper.phase_scan_harm_err = err cav_wrapper.phase_scan_harm_funcion.setParamArr(self.harmonicsAnalyzer.getHrmonicsFunction().getParamArr()) #----make theory graph plot x_arr = [] y_arr = [] for i in range(73): phase = -180.0 + 5.0*i y = harm_function.getValue(phase) x_arr.append(phase) y_arr.append(y) gdTh.addPoint(x_arr,y_arr) return true def fakeMakePhaseScanStep(self,cav_phase,cav_wrapper): cav_wrappers = self.scl_long_tuneup_controller.cav_wrappers mass = self.scl_long_tuneup_controller.mass/1.0e+6 bpm_freq = self.scl_long_tuneup_controller.bpm_freq c = self.scl_long_tuneup_controller.c_light cav_pos0 = cav_wrappers[0].pos max_pos = cav_wrappers[len(cav_wrappers)-1].pos - cav_pos0 cav_pos = cav_wrapper.pos eKin_in = 185.6+650.0*(cav_pos-cav_pos0)/max_pos cav_phase_offset = 30. phase = makePhaseNear(cav_phase + cav_phase_offset,0.) eKin = eKin_in if(self.scl_long_tuneup_controller.cav0_wrapper != cav_wrapper): eKin += 8.0*math.cos(2.0*math.pi*phase/360.) else: eKin = 185.6 gamma = (eKin+mass)/mass beta = math.sqrt(1.0 - 1.0/gamma**2) c = 2.99792458e+8 freq = 402.5e+6 bpm_phase_coef = 360.0*freq/(c*beta) #print "debug cav_phase=",cav_phase," beta=",beta," eKin=",eKin," cav_pos=",cav_pos," coeff=",bpm_phase_coef bpm_wrappers = cav_wrapper.bpm_wrappers for bpm_wrapper in bpm_wrappers: if(cav_wrapper.bpm_amp_phase_dict.has_key(bpm_wrapper)): (graphDataAmp,graphDataPhase) = cav_wrapper.bpm_amp_phase_dict[bpm_wrapper] if(bpm_wrapper.pos < cav_pos): graphDataAmp.addPoint(cav_phase,10.0) graphDataPhase.addPoint(cav_phase,20.0) continue bpm_phase = makePhaseNear(bpm_phase_coef*(bpm_wrapper.pos - cav_pos),0.) bpm_phase += 1.0*(random.random()-0.5) bpm_amp = 25.0*1./(1.+(bpm_wrapper.pos-cav_pos)/20.) graphDataAmp.addPoint(cav_phase,bpm_amp) old_bpm_phase = 0. if(graphDataPhase.getNumbOfPoints() > 0): old_bpm_phase = graphDataPhase.getY(graphDataPhase.getNumbOfPoints() - 1) graphDataPhase.addPoint(cav_phase,makePhaseNear(bpm_phase,old_bpm_phase)) return true def allBPMs_PhaseWrapper(self,cav_wrapper): # it will wrap all BPM phases for the cvity by iteration from the BPM closest to cavity if(not cav_wrapper.isGood): return cav_pos = cav_wrapper.pos bpm_wrappers = [] for bpm_ind in range(len(cav_wrapper.bpm_wrappers)): bpm_wrapper = cav_wrapper.bpm_wrappers[bpm_ind] res_bool = cav_wrapper.bpm_amp_phase_dict.has_key(bpm_wrapper) res_bool = res_bool and bpm_wrapper.isGood res_bool = res_bool and (bpm_wrapper.pos > cav_pos) if(res_bool): bpm_wrappers.append(bpm_wrapper) for bpm_ind in range(len(bpm_wrappers)-1): (graphDataAmp0,graphDataPhase0) = cav_wrapper.bpm_amp_phase_dict[bpm_wrappers[bpm_ind]] (graphDataAmp1,graphDataPhase1) = cav_wrapper.bpm_amp_phase_dict[bpm_wrappers[bpm_ind+1]] if(graphDataPhase0.getNumbOfPoints() < 1): break if(graphDataPhase0.getNumbOfPoints() != graphDataPhase1.getNumbOfPoints()): txt = "Phase Wrapper BPM=",bpm_wrappers[bpm_ind].alias txt += " and BPM=",bpm_wrappers[bpm_ind+1].alias txt += " have different number of RF phase points n1=",graphDataPhase0.getNumbOfPoints() txt += " n2=",graphDataPhase1.getNumbOfPoints() self.scl_long_tuneup_controller.getMessageTextField().setText(txt) print "debug ===================" print txt time.sleep(10.) return false y_arr = [] for ip in range(graphDataPhase1.getNumbOfPoints()): y_arr.append(graphDataPhase1.getY(ip)) base_phase_diff = y_arr[0] - graphDataPhase0.getY(0) for ip in range(1,graphDataPhase0.getNumbOfPoints()): y0 = graphDataPhase0.getY(ip) y_arr[ip] = makePhaseNear(y_arr[ip],y0+base_phase_diff) base_phase_diff = y_arr[ip] - y0 #move all data by 360. to make the avg close to 0. y_avg = 0. for y in y_arr: y_avg += y if(len(y_arr) > 1): y_avg /= len(y_arr) y_shift = int(y_avg/360.)*360. for ip in range(len(y_arr)): y_arr[ip] -= y_shift #--- update all bpm phases graphDataPhase1.updateValuesY(y_arr) # recreate phase difference cav_wrapper.recalculatePhaseDiffData() return true