def df2run(myDF, pythonData=None, command_log_file='log.madx', stdout_file='stdout.madx', verbose=False): ''' It runs the MADX dataframe using the MADX extended syntax. myDF: the MADX DF to run. command_log_file: the filename of the logging file. Use the None variable not to log. stdout_file: the filename of the file to redirect the stdout. Use the None variable not to log. verbose: boolean flag to have verbose output during the execution. ''' if command_log_file == None: if stdout_file == None: madx = Madx() else: with open(stdout_file, 'w') as f: madx = Madx(stdout=f) else: if stdout_file == None: madx = Madx(command_log=command_log_file) else: with open(stdout_file, 'w') as f: madx = Madx(stdout=f, command_log=command_log_file) myGlobals = [] for section in myDF.iterrows(): print(section[0]) start_time = time.time() codeSubSections = section[1]['Code subsections'] pythonDictionary = {} with madx.batch(): myCheck = [list(code.keys())[0] for code in codeSubSections] if verbose: print(codeSubSections) if ('madx' in myCheck) & ('python' in myCheck): raise Exception( 'Do not put madx and python code in the same section!') for code in codeSubSections: myType = list(code.keys())[0] if myType == 'markdown': pass elif myType == 'python': exec(code['python']) # local variables elif myType == 'madx': madx.input(code['madx']) else: assert (0) execution_time_s = time.time() - start_time myDict = {} myDict = dict(madx.globals) myDict['execution time [s]'] = execution_time_s myDict['pythonDictionary'] = pythonDictionary myDict['Code subsections'] = section[1]['Code subsections'] myDict['Code section'] = section[1]['Code section'] myGlobals.append(myDict) profileDF = pd.DataFrame(myGlobals, index=myDF.index) return profileDF
def get_closest_tune_approach( madx: Madx, accelerator: str = None, sequence: str = None, varied_knobs: Sequence[str] = None, telescopic_squeeze: bool = False, explicit_targets: Tuple[float, float] = None, step: float = 1e-7, calls: float = 100, tolerance: float = 1e-21, ) -> float: """ Provided with an active `cpymad` class after having ran a script, tries to match the tunes to their mid-fractional tunes. The difference between this mid-tune and the actual matched tune is the closest tune approach. NOTA BENE: This assumes your lattice has previously been matched to desired tunes and chromaticities, as it will determine the appropriate targets from the Madx instance's internal tables. Args: madx (cpymad.madx.Madx): an instanciated cpymad Madx object. accelerator (str): name of the accelerator, used to determmine knobs if 'variables' not given. Automatic determination will only work for LHC and HLLHC. sequence (str): name of the sequence you want to activate for the tune matching. varied_knobs (Sequence[str]): the variables names to 'vary' in the MADX routine. An input could be ["kqf", "ksd", "kqf", "kqd"] as they are common names used for quadrupole and sextupole strengths (foc / defoc) in most examples. telescopic_squeeze (bool): LHC specific. If set to True, uses the (HL)LHC knobs for Telescopic Squeeze configuration. Defaults to False. explicit_targets (Tuple[float, float]): if given, will be used as matching targets for Qx, Qy. Otherwise, the target is determined as the middle of the current fractional tunes. Defaults to None. step (float): step size to use when varying knobs. calls (int): max number of varying calls to perform. tolerance (float): tolerance for successfull matching. Returns: The closest tune approach, in absolute value. """ if accelerator and not varied_knobs: logger.trace( f"Getting knobs from default {accelerator.upper()} values") varied_knobs = get_lhc_tune_and_chroma_knobs( accelerator=accelerator, beam=int(sequence[-1]), telescopic_squeeze=telescopic_squeeze) logger.debug("Saving knob values to restore after closest tune approach") saved_knobs: Dict[str, float] = { knob: madx.globals[knob] for knob in varied_knobs } logger.trace(f"Saved knobs are {saved_knobs}") if explicit_targets: qx_target, qy_target = explicit_targets q1, q2 = qx_target, qy_target # the integer part is used later on else: logger.trace( "Retrieving tunes and chromaticities from internal tables") q1, q2 = madx.table.summ.q1[0], madx.table.summ.q2[0] dq1, dq2 = madx.table.summ.dq1[0], madx.table.summ.dq2[0] logger.trace( f"Retrieved values are q1 = {q1}, q2 = {q2}, dq1 = {dq1}, dq2 = {dq2}" ) logger.trace("Determining target tunes for closest approach") middle_of_fractional_tunes = (_fractional_tune(q1) + _fractional_tune(q2)) / 2 qx_target = int(q1) + middle_of_fractional_tunes qy_target = int(q2) + middle_of_fractional_tunes logger.debug(f"Targeting tunes Qx = {qx_target} | Qy = {qy_target}") logger.info( "Performing closest tune approach routine, matching should fail at DeltaQ = dqmin" ) match_tunes_and_chromaticities( madx, accelerator, sequence, qx_target, qy_target, varied_knobs=varied_knobs, step=step, calls=calls, tolerance=tolerance, ) logger.debug("Retrieving tune separation from internal tables") dqmin = madx.table.summ.q1[0] - madx.table.summ.q2[0] - (int(q1) - int(q2)) logger.info("Restoring saved knobs") with madx.batch(): madx.globals.update(saved_knobs) madx.twiss() return abs(dqmin)
myDF = pd.DataFrame(body, index=title, columns=['Code string']) # %% Run MADX madx = Madx() # %% import time myGlobals = [] mySmallDF = myDF myString = '' for block in mySmallDF.iterrows(): print(block[0]) start_time = time.time() myString = myString + '! %%' + block[0] + '\n' + block[1]['Code string'][ 0:-1] with madx.batch(): madx.input('! %%' + block[0] + '\n' + block[1]['Code string'][0:-1]) execution_time_s = time.time() - start_time myDict = {} myDict = dict(madx.globals) myDict['execution time [s]'] = execution_time_s myGlobals.append(myDict) profileDF = pd.DataFrame(myGlobals, index=mySmallDF.index) # %% with open('inverse.mask', 'w') as fid: fid.write(myString) # %% # %% madx.input(aux[2]) # %%