Merge pull request #3 from jochenstahn/call_string

new management of defaults, migration of 'call_string'
This commit is contained in:
Jochen Stahn
2024-03-14 13:42:08 +01:00
committed by GitHub
5 changed files with 178 additions and 131 deletions

View File

@@ -2,7 +2,7 @@ import argparse
from datetime import date
from .logconfig import update_loglevel
from .options import ReaderConfig, EOSConfig, ExperimentConfig, OutputConfig, ReductionConfig
from .options import ReaderConfig, EOSConfig, ExperimentConfig, OutputConfig, ReductionConfig, Defaults
def commandLineArgs():
@@ -16,20 +16,20 @@ def commandLineArgs():
clas = argparse.ArgumentParser(description = msg)
input_data = clas.add_argument_group('input data')
input_data.add_argument("-n", "--fileIdentifier",
default = ['0'],
input_data.add_argument("-f", "--fileIdentifier",
required = True,
nargs = '+',
help = "file number(s) or offset (if negative)")
input_data.add_argument("-r", "--normalisationFileIdentifier",
default = [],
help = "file number(s) or offset (if < 1)")
input_data.add_argument("-n", "--normalisationFileIdentifier",
default = Defaults.normalisationFileIdentifier,
nargs = '+',
help = "file number(s) of normalisation measurement")
input_data.add_argument("-d", "--dataPath",
type = str,
default = '.',
default = Defaults.dataPath,
help = "relative path to directory with .hdf files")
input_data.add_argument("-Y", "--year",
default = date.today().year,
default = Defaults.year,
type = int,
help = "year the measurement was performed")
input_data.add_argument("-sub", "--subtract",
@@ -37,17 +37,18 @@ def commandLineArgs():
output = clas.add_argument_group('output')
output.add_argument("-o", "--outputName",
default = "fromEOS",
default = Defaults.outputName,
help = "output file name (withot suffix)")
output.add_argument("-of", "--outputFormat",
nargs = '+',
default = ['Rqz.ort'])
default = Defaults.outputFormat,
help = "one of [Rqz.ort, Rlt.ort]")
output.add_argument("--offSpecular",
type = bool,
default = False,
default = Defaults.offSpecular,
)
output.add_argument("-a", "--qResolution",
default = 0.01,
output.add_argument("-r", "--qResolution",
default = Defaults.qResolution,
type = float,
help = "q_z resolution")
output.add_argument("-ts", "--timeSlize",
@@ -56,7 +57,7 @@ def commandLineArgs():
help = "time slizing <interval> ,[<start> [,stop]]")
output.add_argument("-s", "--scale",
nargs = '+',
default = [1],
default = Defaults.scale,
type = float,
help = "scaling factor for R(q_z)")
output.add_argument("-S", "--autoscale",
@@ -66,56 +67,58 @@ def commandLineArgs():
masks = clas.add_argument_group('masks')
masks.add_argument("-l", "--lambdaRange",
default = [2., 15.],
default = Defaults.lambdaRange,
nargs = 2,
type = float,
help = "wavelength range")
masks.add_argument("-t", "--thetaRange",
default = [-12., 12.],
default = Defaults.thetaRange,
nargs = 2,
type = float,
help = "absolute theta range")
masks.add_argument("-T", "--thetaRangeR",
default = [-12., 12.],
default = Defaults.thetaRangeR,
nargs = 2,
type = float,
help = "relative theta range")
masks.add_argument("-y", "--yRange",
default = [11, 41],
default = Defaults.yRange,
nargs = 2,
type = int,
help = "detector y range")
masks.add_argument("-q", "--qzRange",
default = [0.005, 0.30],
default = Defaults.qzRange,
nargs = 2,
type = float,
help = "q_z range")
overwrite = clas.add_argument_group('overwrite')
overwrite.add_argument("-cs", "--chopperSpeed",
default = Defaults.chopperSpeed,
type = float,
help = "chopper speed in rpm")
overwrite.add_argument("-cp", "--chopperPhase",
default = -13.5,
default = Defaults.chopperPhase,
type = float,
help = "chopper phase")
overwrite.add_argument("-co", "--chopperPhaseOffset",
default = -5,
default = Defaults.chopperPhaseOffset,
type = float,
help = "phase offset between chopper opening and trigger pulse")
overwrite.add_argument("-m", "--muOffset",
default = 0.,
default = Defaults.muOffset,
type = float,
help = "mu offset")
overwrite.add_argument("-mu", "--mu",
default = 0,
default = Defaults.mu,
type = float,
help ="value of mu")
overwrite.add_argument("-nu", "--nu",
default = 0,
default = Defaults.nu,
type = float,
help = "value of nu")
overwrite.add_argument("-sm", "--sampleModel",
default = Defaults.sampleModel,
type = str,
help = "1-line orso sample model description")

View File

@@ -132,7 +132,7 @@ class AmorData:
if self.readHeaderInfo:
self.read_header_info()
logging.info(f'# data from file: {fileName}')
logging.warning(f' data from file: {fileName}')
self.read_individual_header()
# add header content
@@ -151,7 +151,7 @@ class AmorData:
self.header.measurement_additional_files.append(fileio.File(file=fileName.split('/')[-1], timestamp=self.fileDate))
else:
self.header.measurement_data_files.append(fileio.File(file=fileName.split('/')[-1], timestamp=self.fileDate))
logging.info(f'# mu = {self.mu:6.3f}, nu = {self.nu:6.3f}, kap = {self.kap:6.3f}, kad = {self.kap:6.3f}')
logging.info(f' mu = {self.mu:6.3f}, nu = {self.nu:6.3f}, kap = {self.kap:6.3f}, kad = {self.kap:6.3f}')
# TODO: should extract monitor from counts or beam current times time
self.monitor1 = self.ctime
@@ -177,7 +177,7 @@ class AmorData:
self.filter_qz_range(norm)
logging.info(f'# number of events: total = {totalNumber:7d}, filtered = {np.shape(self.lamda_e)[0]:7d}')
logging.info(f' number of events: total = {totalNumber:7d}, filtered = {np.shape(self.lamda_e)[0]:7d}')
def filter_qz_range(self, norm):
if self.config.qzRange[1]<0.3 and not norm:
@@ -311,7 +311,7 @@ class AmorData:
def read_header_info(self):
# read general information and first data set
logging.info(f'# meta data from: {self.file_list[0]}')
logging.info(f' meta data from: {self.file_list[0]}')
self.hdf = h5py.File(self.file_list[0], 'r', swmr=True)
title = self.hdf['entry1/title'][0].decode('utf-8')
proposal_id = self.hdf['entry1/proposal_id'][0].decode('utf-8')

View File

@@ -14,7 +14,7 @@ from . import __version__
class Header:
"""orso compatible output file header content"""
def __init__(self, config):
def __init__(self):
self.owner = None
self.experiment = None
self.sample = None
@@ -25,7 +25,7 @@ class Header:
self.reduction = fileio.Reduction(
software = fileio.Software('eos', version=__version__),
call = self.call_string(config),
call = 'placeholder',
computer = platform.node(),
timestamp = datetime.now(),
creator = None,
@@ -71,91 +71,3 @@ class Header:
callString += f' -Y {datetime.now().year}'
return callString
#-------------------------------------------------------------------------------------------------
def call_string(self, config):
self.experiment_config = config.experiment
self.reader_config = config.reader
self.reduction_config = config.reductoin
self.output_config = config.output
base = 'python eos.py'
inpt = ''
if self.reader_config.year:
inpt += f' --year {self.reader_config.year}'
else:
inpt += f' --year {datetime.now().year}'
if self.reader_config.dataPath != '.':
inpt += f' --dataPath {self.reader_config.dataPath}'
if self.reduction_config.subtract:
inpt += f' -subtract {self.reduction_config.subtract}'
if self.reduction_config.normalisationFileIdentifier:
inpt += f' -r {" ".join(self.reduction_config.normalisationFileIdentifier)}'
# get file list somehow
if False:
pass
#inpt += f' -n {file_list}'
else:
inpt += f' -n {" ".join(self.reduction_config.fileIdentifier)}'
otpt = ''
if self.reduction_config.qResolution:
otpt += f' -q {self.reduction_config.qResolution}'
if self.output_config.outputFormats != 'Rqz.ort':
otpt = f' -of {" ".join(self.output_config.outputFormats)}'
if self.output_config.outputName:
otpt += f' -o {self.output_config.outputName}'
else:
pass
# default name
mask = ''
if self.experiment_config.yRange != [11, 41]:
mask += f' -y {" ".join(str(ii) for ii in self.experiment_config.yRange)}'
if self.experiment_config.lambdaRange!= [2, 15]:
mask += f' -l {" ".join(str(ff) for ff in self.experiment_config.lambdaRange)}'
if self.reduction_config.thetaRange != [-12, 12]:
mask += f' --thetaRange {" ".join(str(ff) for ff in self.reduction_config.thetaRange)}'
elif self.reduction_config.thetaRangeR != [-12, 12]:
mask += f' -t {" ".join(str(ff) for ff in self.reduction_config.thetaRangeR)}'
if self.experiment_config.qzRange!= [0.005, 0.3]:
mask += f' -q {" ".join(str(ff) for ff in self.experiment_config.qzRange)}'
para = ''
if self.experiment_config.chopperPhase != -13.5:
para += f' --chopperPhase {self.experiment_config.chopperPhase}'
if self.experiment_config.chopperPhaseOffset != -5:
para += f' --chopperPhaseOffset {self.experiment_config.chopperPhaseOffset}'
if self.experiment_config.mu:
para += f' --mu {self.experiment_config.mu}'
elif self.experiment_config.muOffset:
para += f' --muOffset {self.experiment_config.muOffset}'
if self.experiment_config.nu:
para += f' --nu {self.experiment_config.nu}'
modl = ''
if self.experiment_config.sampleModel:
modl += f" --sampleModel '{self.experiment_config.sampleModel}'"
acts = ''
if self.reduction_config.autoscale:
acts += f' --autoscale {" ".join(str(ff) for ff in self.reduction_config.autoscale)}'
if self.reduction_config.scale != [1]:
acts += f' --scale {self.reduction_config.scale}'
if self.reduction_config.timeSlize:
acts += f' --timeSlize {" ".join(str(ff) for ff in self.reduction_config.timeSlize)}'
#experiment_config = ExperimentConfig(
# offSpecular = clas.offSpecular,
# )
mlst = base + ' ' + inpt + ' ' + otpt
if mask:
mlst += ' ' + mask
if para:
mlst += ' ' + para
if acts:
mlst += ' ' + acts
if modl:
mlst += ' ' + modl
return mlst

View File

@@ -3,6 +3,37 @@ Classes for stroing various configurations needed for reduction.
"""
from dataclasses import dataclass, field
from typing import Optional, Tuple
from datetime import datetime
class Defaults:
#fileIdentifier
normalisationFileIdentifier = []
dataPath = '.'
year = datetime.now().year
#subtract
outputName = "fromEOS"
outputFormat = ['Rqz.ort']
offSpecular = False
qResolution = 0.01
#timeSlize
scale = [1]
#autoscale
lambdaRange = [2., 15.]
thetaRange = [-12., 12.]
thetaRangeR = [-0.7, 0.7]
yRange = [11, 41]
qzRange = [0.005, 0.30]
chopperSpeed = 500
chopperPhase = -13.5
chopperPhaseOffset = -5
muOffset = 0
mu = 0
nu = 0
sampleModel = None
#
@dataclass
class ReaderConfig:
@@ -18,7 +49,7 @@ class ExperimentConfig:
qzRange: Tuple[float, float]
sampleModel: Optional[str] = None
chopperPhaseOffset: float = 0.0
chopperPhaseOffset: float = 0
mu: Optional[float] = None
nu: Optional[float] = None
muOffset: Optional[float] = None
@@ -47,5 +78,104 @@ class OutputConfig:
class EOSConfig:
reader: ReaderConfig
experiment: ExperimentConfig
reductoin: ReductionConfig
output: OutputConfig
reduction: ReductionConfig
output: OutputConfig
_call_string_overwrite=None
#@property
#def call_string(self)->str:
# if self._call_string_overwrite:
# return self._call_string_overwrite
# else:
# return self.calculate_call_string()
def call_string(self):
base = 'python eos.py'
inpt = ''
if self.reader_config.year:
inpt += f' -Y {self.reader_config.year}'
else:
inpt += f' -Y {datetime.now().year}'
if self.reader_config.dataPath != '.':
inpt += f' --dataPath {self.reader_config.dataPath}'
if self.reduction_config.subtract:
inpt += f' -subtract {self.reduction_config.subtract}'
if self.reduction_config.normalisationFileIdentifier:
inpt += f' -n {" ".join(self.reduction_config.normalisationFileIdentifier)}'
if self.reduction_config.fileIdentifier:
inpt += f' -f {" ".join(self.reduction_config.fileIdentifier)}'
otpt = ''
if self.reduction_config.qResolution:
otpt += f' -r {self.reduction_config.qResolution}'
if self.output_config.outputName:
otpt += f' -o {self.output_config.outputName}'
if self.output_config.outputFormats != ['Rqz.ort']:
otpt += f' -of {" ".join(self.output_config.outputFormats)}'
mask = ''
if self.experiment_config.yRange != Defaults.yRange:
mask += f' -y {" ".join(str(ii) for ii in self.experiment_config.yRange)}'
if self.experiment_config.lambdaRange!= Defaults.lambdaRange:
mask += f' -l {" ".join(str(ff) for ff in self.experiment_config.lambdaRange)}'
if self.reduction_config.thetaRange != Defaults.thetaRange:
mask += f' -T {" ".join(str(ff) for ff in self.reduction_config.thetaRange)}'
elif self.reduction_config.thetaRangeR != Defaults.thetaRangeR:
mask += f' -t {" ".join(str(ff) for ff in self.reduction_config.thetaRangeR)}'
if self.experiment_config.qzRange!= Defaults.qzRange:
mask += f' -q {" ".join(str(ff) for ff in self.experiment_config.qzRange)}'
para = ''
if self.experiment_config.chopperPhase != Defaults.chopperPhase:
para += f' --chopperPhase {self.experiment_config.chopperPhase}'
if self.experiment_config.chopperPhaseOffset != Defaults.chopperPhaseOffset:
para += f' --chopperPhaseOffset {self.experiment_config.chopperPhaseOffset}'
if self.experiment_config.mu:
para += f' --mu {self.experiment_config.mu}'
elif self.experiment_config.muOffset:
para += f' --muOffset {self.experiment_config.muOffset}'
if self.experiment_config.nu:
para += f' --nu {self.experiment_config.nu}'
modl = ''
if self.experiment_config.sampleModel:
modl += f" --sampleModel '{self.experiment_config.sampleModel}'"
acts = ''
if self.reduction_config.autoscale:
acts += f' --autoscale {" ".join(str(ff) for ff in self.reduction_config.autoscale)}'
if self.reduction_config.scale != Defaults.scale:
acts += f' --scale {self.reduction_config.scale}'
if self.reduction_config.timeSlize:
acts += f' --timeSlize {" ".join(str(ff) for ff in self.reduction_config.timeSlize)}'
# TODO: experiment_config = ExperimentConfig(
# offSpecular = clas.offSpecular,
# )
mlst = base + inpt + otpt
if mask:
mlst += mask
if para:
mlst += para
if acts:
mlst += acts
if modl:
mlst += modl
if len(mlst) > 70:
mlst = base + ' ' + inpt + ' ' + otpt
if mask:
mlst += ' ' + mask
if para:
mlst += ' ' + para
if acts:
mlst += ' ' + acts
if modl:
mlst += ' ' + modl
return mlst

View File

@@ -15,10 +15,12 @@ class AmorReduction:
def __init__(self, config: EOSConfig):
self.experiment_config = config.experiment
self.reader_config = config.reader
self.reduction_config = config.reductoin
self.reduction_config = config.reduction
self.output_config = config.output
self.grid = Grid(config.reductoin.qResolution)
self.header = Header(config)
self.grid = Grid(config.reduction.qResolution)
self.header = Header()
self.header.reduction.call = EOSConfig.call_string(self)
def reduce(self):
if not os.path.exists(f'{self.reader_config.dataPath}'):
@@ -211,13 +213,13 @@ class AmorReduction:
def save_Rqz(self):
fname = os.path.join(self.reader_config.dataPath, f'{self.output_config.outputName}.Rqz.ort')
logging.warning(f' {fname}')
logging.warning(f' {fname}')
theSecondLine = f' {self.header.experiment.title} | {self.header.experiment.start_date} | sample {self.header.sample.name} | R(q_z)'
fileio.save_orso(self.datasetsRqz, fname, data_separator='\n', comment=theSecondLine)
def save_Rtl(self):
fname = os.path.join(self.reader_config.dataPath, f'{self.output_config.outputName}.Rlt.ort')
logging.warning(f' {fname}')
logging.warning(f' {fname}')
theSecondLine = f' {self.header.experiment.title} | {self.header.experiment.start_date} | sample {self.header.sample.name} | R(lambda, theta)'
fileio.save_orso(self.datasetsRlt, fname, data_separator='\n', comment=theSecondLine)
@@ -229,7 +231,7 @@ class AmorReduction:
if len(filter_q[filter_q]) > 0:
scale = np.sum(R_q[filter_q]**2/dR_q[filter_q]) / np.sum(R_q[filter_q]/dR_q[filter_q])
else:
logging.warning('# automatic scaling not possible')
logging.warning(' automatic scaling not possible')
scale = 1.
else:
filter_q = np.where(np.isnan(pR_q*R_q), False, True)
@@ -239,11 +241,11 @@ class AmorReduction:
scale = np.sum(R_q[filter_q]**3 * pR_q[filter_q] / (dR_q[filter_q]**2 * pdR_q[filter_q]**2)) \
/ np.sum(R_q[filter_q]**2 * pR_q[filter_q]**2 / (dR_q[filter_q]**2 * pdR_q[filter_q]**2))
else:
logging.warning('# automatic scaling not possible')
logging.warning(' automatic scaling not possible')
scale = 1.
R_q /= scale
dR_q /= scale
logging.debug(f'# scaling factor = {scale}')
logging.debug(f' scaling factor = {scale}')
return R_q, dR_q
@@ -296,7 +298,7 @@ class AmorReduction:
name = f'{name}_{normalisation_list[i]}'
n_path = os.path.join(dataPath, f'{name}.norm')
if os.path.exists(n_path):
logging.info(f'# normalisation matrix: found and using {n_path}')
logging.warning(f'normalisation matrix: found and using {n_path}')
#self.norm_lz = np.loadtxt(f'{dataPath}/{name}.norm')
#with open(n_path, 'r') as fh:
# fh.readline()
@@ -310,7 +312,7 @@ class AmorReduction:
self.normFileList[i] = entry.split('/')[-1]
self.header.measurement_additional_files = self.normFileList
else:
logging.info(f'# normalisation matrix: using the files {normalisation_list}')
logging.warning(f'normalisation matrix: using the files {normalisation_list}')
fromHDF = AmorData(header=self.header,
reader_config=self.reader_config,
config=self.experiment_config,