def run(args: List[str] = None, phil: libtbx.phil.scope = phil_scope) -> None: """ Run dials.anvil_correction as from the command line. Take integrated experiment lists and reflection tables and correct the all the integrated intensities for the estimated attenuation by the diamond anvils. Args: args: The arguments supplied by the user (default: sys.argv[1:]). phil: The PHIL scope definition (default: phil_scope, the master PHIL scope for this program). """ usage = "dials.anvil_correction [options] integrated.expt integrated.refl" parser = OptionParser( usage=usage, phil=phil, read_reflections=True, read_experiments=True, check_format=False, epilog=__doc__, ) params, options = parser.parse_args(args=args, show_diff_phil=False) # Log the difference between the PHIL scope definition and the active PHIL scope, # which will include the parsed user inputs. diff_phil = parser.diff_phil.as_str() if diff_phil: logger.info("The following parameters have been modified:\n%s", diff_phil) # Check that at least one reflection table and experiment list have been provided. input_errors = [] if not params.input.experiments: input_errors.append( "Please provide at least one valid experiment list (.expt) file.") if not params.input.reflections: input_errors.append( "Please provide at least one valid reflection table (.refl) file.") if input_errors: sys.exit("\n".join([parser.format_help()] + input_errors)) if not np.linalg.norm(params.anvil.normal): sys.exit( "It seems you have provided a surface normal vector with zero length." ) # Check that the anvil surface normal really is normalised. dac_norm = params.anvil.normal / np.linalg.norm(params.anvil.normal) # Configure the logging. dials.util.log.config(options.verbose, logfile=params.output.log) # These functions are commonly used to collate the input. experiments = flatten_experiments(params.input.experiments) reflections_list = flatten_reflections(params.input.reflections) # Work around parse_multiple_datasets dropping unindexed reflections. unindexed = flex.reflection_table() for r_table in reflections_list: unindexed.extend(r_table.select(r_table["id"] == -1)) # Get a single reflection table per experiment object. reflections_list = parse_multiple_datasets(reflections_list) reflections_list = sort_tables_to_experiments_order( reflections_list, experiments) # Record the density of diamond in g·cm⁻³ (for consistency with NIST tables, # https://doi.org/10.18434/T4D01F). density = params.anvil.density / 1000 # g·cm⁻³ # Correct for the attenuation of the incident and diffracted beams by the diamond # anvil cell. logger.info( "Correcting integrated reflection intensities for attenuation by the diamond " "anvil cell.") for experiment, reflections in zip(experiments, reflections_list): correct_intensities_for_dac_attenuation(experiment, reflections, dac_norm, params.anvil.thickness, density) logger.info("Done.") # Do optional experiment list file output here. if params.output.experiments: logger.info("Writing the experiment list to %s", params.output.experiments) experiments.as_file(params.output.experiments) logger.info("Writing the reflection table to %s", params.output.reflections) # Collate reflections into a single reflection table and save it to file. reflections = unindexed for r_table in reflections_list: reflections.extend(r_table) del reflections_list reflections.as_file(params.output.reflections)