subroutine close_bump (ing_name, ix_ing, cu_delta_in, u, graph, err_flag) use cesrv_struct use cesrv_interface implicit none type (universe_struct) u type (group_info_struct) grp type (graph_struct) graph type (ele_struct), pointer :: ele, ele1, ele2 integer cu_delta, cu_delta_in, ix_var(6), cu_del integer i, j, ix, ios, cu_now, cu_max, cu_min, n_slave, cu_orig integer cu1, cu2, idum, ix_start, ix_end, dcu1, dcu2 integer ix_start_bump, ix_end_bump, ix_ing, ix_ele, n_ring integer iv1, iv2, dcu(2), old_coef(6), new_coef(6), ix_var_use(2) integer, save :: i_use(2) = 0 real(rp) del1, del2, coef, merit real(rp) a11, a12, a21, a22, b1, b2, slope1, slope2, det real(rp) dvar(2), a_cu(6) real rdum(1) character det_list*120, ing_name*12 logical err_flag, make_meas, veto(0:120), ok, doit ! init group, etc. err_flag = .true. ! assume the worst call setup_group (ing_name, ix_ing, 0, 0, grp, ok, .true.) if (.not. ok) return ! IX_VAR() matches group records with elements in u%var array grp_loop: do i = 1, grp%n_rec if (.not. grp%rec(i)%exists) exit n_slave = i do j = 1, size(u%var) if (grp%rec(i)%name == u%var(j)%db_node_name .and. & grp%rec(i)%l1 == u%var(j)%ix_db) then ix_var(i) = j cycle grp_loop endif enddo print *, 'ERROR: CANNOT MATCH GROUP RECORD WITH ANY CESRV VARIABLE' print *, ' CANNOT MATCH: ', grp%rec(i)%name, grp%rec(i)%l1 return enddo grp_loop if (any(grp%rec(n_slave+1:grp%n_rec)%exists)) then print *, 'ERROR: GROUP ELEMENTS NOT IN ORDER!' return endif ! which variables to vary? print '(a, 4(/, 4x, i2, 2a))', ' Current elements: ', & (i, ') ', u%var(ix_var(i))%name, i = 1, n_slave) print '(a, $)', ' Choose 2 elements to vary (by number): ' if (logic%command_file_open) then read (logic%iu_command_file, *, err = 9000, end = 9000) i_use(1), i_use(2) else read (*, *, iostat = ios) i_use(1), i_use(2) endif if (ios /= 0 .or. i_use(1) < 1 .or. i_use(1) > n_slave .or. & i_use(2) < 1 .or. i_use(2) > n_slave) then print *, 'ERROR READING NUMBERS.' return endif ! if no orbit measurement wanted then try to figure out what the cu_delta was make_meas = .false. call cesrv_logic_get ('Y', 'N', 'Make an orbit measurement?', make_meas) if (.not. make_meas) then print *, 'Element CU_Change Icoef dCU_Group' do i = 1, n_slave ix = ix_var(i) call inverse_cross_corr (u%var(ix)%db_node_name, u%var(ix)%cu_saved_ref, & u%var(ix)%cu_saved, cu_del, u%var(ix)%ix_db, u%var(ix)%ix_db) ! cu_del = u%var(ix)%cu_saved - u%var(ix)%cu_saved_ref a_cu(i) = cu_del * 1000.0 / grp%rec(i)%icoef print '(1x, a, i8, 2i10)', u%var(ix)%name, & cu_del, grp%rec(i)%icoef, nint(a_cu(i)) enddo cu_delta = sum(a_cu(1:n_slave)) / n_slave do i = 1, n_slave if (abs(cu_delta - a_cu(i)) > max(0.01 * abs(cu_delta), 5.0_rp)) then print *, "ERROR: I'M TRYING TO CALCULATE HOW MUCH THE GROUP KNOB WAS" print *, " CHANGED BY USING THE CHANGE IN A STEERING AND THE" print *, " GROUP KNOB COEFICIENTS. I'M NOT GETTING CONSISTANT" print *, " RESULTS AMONG THE STEERINGS. POSSIBLE REASONS:" print *, " 1) YOU HAVE GIVEN ME THE WRONG ORBITS." print *, " 2) YOU HAVE GIVEN ME THE WRONG GROUP KNOB." print *, " 3) THE GROUP COEFICIENTS I AM USING ARE NOT WHAT" print *, " THEY WERE WHEN THE DATA WAS TAKEN." print *, " I WILL STOP HERE." return endif enddo print *, 'Delta CU for the Group Knob used:', cu_delta ! here to measure an orbit.... ! calculate delta else if (cu_delta_in == 0) then cu_delta = 200 else cu_delta = cu_delta_in endif ! calc what max and min should be. ! try to make max and min not near 0 cu_max = 100000 cu_min = -100000 do i = 1, n_slave ix = ix_var(i) call vxgetn (u%var(ix)%db_node_name, u%var(ix)%ix_db, u%var(ix)%ix_db, cu_now) del1 = u%var(ix)%cu_high_lim - cu_now del2 = u%var(ix)%cu_low_lim - cu_now coef = grp%rec(i)%icoef / 1000.0 if (coef == 0) cycle dcu1 = del1 / coef dcu2 = del2 / coef cu_max = min(cu_max, max(dcu1, dcu2)) cu_min = max(cu_min, min(dcu1, dcu2)) enddo ! calculate range if (cu_delta > cu_max - cu_min) then print *, 'ERROR: CU_DELTA IS TOO LARGE FOR RANGE OF BUMP KNOB' print *, ' MAX POSITIVE CHANGE FOR KNOB: ', cu_max print *, ' MAX NEGATIVE CHANGE FOR KNOB: ', cu_min return endif call vmgcmd (ing_name, ix_ing, ix_ing, cu_orig) cu1 = min(cu_orig, cu_max - cu_delta) cu2 = cu1 + cu_delta print *, 'Bump set points for the measurement (CU): ', cu1, cu2 ! measure difference orbit call set_and_meas (ing_name, ix_ing, cu1, & orbit_data$, ix_var, n_slave, ref_file$, u, graph, err_flag) if (err_flag) return call set_and_meas (ing_name, ix_ing, cu2, & orbit_data$, ix_var, n_slave, data_file$, u, graph, err_flag) if (err_flag) return cu_del = cu_orig - cu2 call group (idum, ing_name, ix_ing, cu2, cu_del) call vxputn (ing_name, ix_ing, ix_ing, cu_orig) endif ! do measure orbit ! Calculate range of dets not to use. ! We need to be careful about bumps that span IP_L0. if (cu_delta == 0) then print *, 'ERROR: CHANGE IN GROUP KNOB IS 0!' print *, ' WILL QUIT HERE.' return endif n_ring = u%ring%n_ele_track do i = 1, n_slave ix = u%var(ix_var(i))%ix_ele call find_element_ends (u%ring%ele(ix), ele1, ele2) ix_start = ele1%ix_ele ix_end = ele2%ix_ele if (i == 1) then ix_start_bump = ix_start ix_end_bump = ix_end else ix_start = ix_start + n_ring * & nint(float(ix_start_bump - ix_start) / n_ring) ix_start_bump = min(ix_start_bump, ix_start) ix_end = ix_end + n_ring * & nint(float(ix_end_bump - ix_end) / n_ring) ix_end_bump = max(ix_end_bump, ix_end) endif enddo if (ix_start_bump < 0) ix_start_bump = ix_start_bump + n_ring if (ix_end_bump > n_ring) ix_end_bump = ix_end_bump - n_ring veto(:) = .true. det_list = '' do i = lbound(u%orbit%x%d, 1), ubound(u%orbit%x%d, 1) ix_ele = u%orbit%x%d(i)%ix_ele if (ix_end_bump > ix_start_bump) then if (ix_ele < ix_start_bump .or. ix_ele > ix_end_bump) veto(i) = .false. else if (ix_ele < ix_start_bump .neqv. ix_ele < ix_end_bump) veto(i) = .false. endif if (veto(i)) det_list = trim(det_list) // ' ' // u%ring%ele(ix_ele)%name enddo print *, 'Detectors Vetoed: ', trim(det_list) ! calculate steering coefs call dmerit_calc ('normal') call merit_calc (merit) do i = 1, n_slave if (.not. u%var(ix_var(i))%good_opt) then print *, 'ERROR: THE STEERING: ', u%var(ix_var(i))%name print *, ' IS VETOED. I CANNOT CONTINUE.' err_flag = .true. return endif enddo ix_var_use(:) = ix_var(i_use(:)) iv1 = u%var(ix_var_use(1))%ix_dvar iv2 = u%var(ix_var_use(2))%ix_dvar a11 = 0 a12 = 0 a22 = 0 b1 = 0 b2 = 0 do i = 1, size(u%data) if (.not. associated(u%data(i)%d1)) cycle if (u%data(i)%d1%d2%type /= orbit_data$) cycle if (.not. u%data(i)%useit_opt) cycle if (veto(u%data(i)%ix_index)) cycle slope1 = u%dm_dv(u%data(i)%ix_dmeas, iv1) slope2 = u%dm_dv(u%data(i)%ix_dmeas, iv2) a11 = a11 + slope1**2 a12 = a12 + slope1 * slope2 a22 = a22 + slope2**2 b1 = b1 + slope1 * (u%data(i)%meas - u%data(i)%ref) b2 = b2 + slope2 * (u%data(i)%meas - u%data(i)%ref) enddo a21 = a12 det = a11 * a22 - a12 * a21 dvar(1) = ( a22 * b1 - a12 * b2) / det dvar(2) = (-a21 * b1 + a11 * b2) / det dcu(:) = nint(dvar(:) / u%var(ix_var_use(:))%dvar_dcu) old_coef(1:n_slave) = grp%rec(1:n_slave)%icoef new_coef = old_coef new_coef(i_use(:)) = new_coef(i_use(:)) - dcu(:) * 1000 / cu_delta print *, ' Steering Old_coef New_coef' do i = 1, n_slave print '(1x, a9, 2i10)', u%var(ix_var(i))%name, old_coef(i), new_coef(i) grp%rec(i)%icoef = new_coef(i) enddo ! setup plotting call zero_kicks_in_ring (u%ring) ! init model so there are no kicks do i = 1, 2 u%var(ix_var_use(i))%model = dvar(i) call var_bookkeeper (u%var(ix_var_use(i)), u%ring, u%orb) enddo call plot_data_set (graph%top1, plot_meas$) call plot_data_set (graph%bottom1, plot_meas$) call baseline_set (plot_ref$, set_to$, graph%top1) call baseline_set (plot_model$, add$, graph%top1) call baseline_set (plot_ref$, set_to$, graph%bottom1) u%main_title1 = 'Top Plot: Orbit Difference - Model Fit' write (u%main_title2, '(2a, i4, a, i6)') & 'Bottom Plot: Difference Orbit for ', & ing_name, ix_ing, ' With delta CU =', cu_delta err_flag = .false. call plotdo ('X', graph, .false., u) doit = .false. call cesrv_logic_get ('Y', 'N', 'Load New Coefficients?', doit) if (doit) then call change_group (grp, rdum, .false., ok) print *, 'Coefficients Loaded' endif return 9000 continue print *, ' ***ERROR READING STRING FROM COMMAND FILE' logic%command_file_open = .false. end subroutine