def align_beamline( beamLine, hDiv=1.5e-3, vDiv=2.5e-4, nameVCMstripe='Rh', pitch=None, nameDCMcrystal='Si111', bragg=None, energy=9000., fixedExit=20., nameDiagnFoil='top-edge', nameVFMcylinder='Rh', heightVFM=None): beamLine.feMovableMaskLT.set_divergence( beamLine.sources[0], [-hDiv/2, vDiv/2]) beamLine.feMovableMaskRB.set_divergence( beamLine.sources[0], [hDiv/2, -vDiv/2]) print('for {0:.2f}h x {1:.2f}v mrad^2 divergence:'.format( hDiv*1e3, vDiv*1e3)) print('full feMovableMaskLT.opening = [{0[0]:.3f}, {0[1]:.3f}]'.format( beamLine.feMovableMaskLT.opening)) print('full feMovableMaskRB.opening = [{0[0]:.3f}, {0[1]:.3f}]'.format( beamLine.feMovableMaskRB.opening)) print('half feMovableMaskLT.opening = [{0[0]:.3f}, {0[1]:.3f}]'.format( [op/2 for op in beamLine.feMovableMaskLT.opening])) print('half feMovableMaskRB.opening = [{0[0]:.3f}, {0[1]:.3f}]'.format( [op/2 for op in beamLine.feMovableMaskRB.opening])) beamLine.vfm.select_surface(nameVFMcylinder) p = raycing.distance_xy(beamLine.vfm.center, beamLine.sources[0].center) if pitch is None: sinPitch = beamLine.vfm.r * 1.5 / p pitch = float(np.arcsin(sinPitch)) else: sinPitch = np.sin(pitch) beamLine.vfm.R = p / sinPitch beamLine.vcm.select_surface(nameVCMstripe) beamLine.vcm.pitch = pitch beamLine.vcm.set_jacks() p = raycing.distance_xy(beamLine.vcm.center, beamLine.sources[0].center) beamLine.vcm.R = 2. * p / sinPitch beamLine.vcm.get_orientation() print('VCM.p = {0:.1f}'.format(p)) print('VCM.pitch = {0:.6f} mrad'.format(beamLine.vcm.pitch*1e3)) print('VCM.roll = {0:.6f} mrad'.format(beamLine.vcm.roll*1e3)) print('VCM.yaw = {0:.6f} mrad'.format(beamLine.vcm.yaw*1e3)) print('VCM.z = {0:.3f}'.format(beamLine.vcm.center[2])) print('VCM.R = {0:.0f}'.format(beamLine.vcm.R)) print('VCM.dx = {0:.3f}'.format(beamLine.vcm.dx)) print('VCM.jack1.zCalib = {0:.3f}'.format(beamLine.vcm.jack1Calib)) print('VCM.jack2.zCalib = {0:.3f}'.format(beamLine.vcm.jack2Calib)) print('VCM.jack3.zCalib = {0:.3f}'.format(beamLine.vcm.jack3Calib)) print('VCM.tx1 = {0:.3f}'.format(beamLine.vcm.tx1[0])) print('VCM.tx2 = {0:.3f}'.format(beamLine.vcm.tx2[0])) p = raycing.distance_xy(beamLine.fsm2.center, beamLine.vcm.center) fsm2height = beamLine.height + p * np.tan(2 * pitch) beamLine.dcm.select_surface(nameDCMcrystal) p = raycing.distance_xy(beamLine.dcm.center, beamLine.vcm.center) beamLine.dcm.center[2] = beamLine.height + p * np.tan(2 * pitch) beamLine.dcm.set_jacks() aCrystal = beamLine.dcm.material[ beamLine.dcm.surface.index(nameDCMcrystal)] dSpacing = aCrystal.d print('DCM.crystal = {0}'.format(nameDCMcrystal)) print('DCM.dSpacing = {0:.6f} angsrom'.format(dSpacing)) if bragg is None: theta = float(np.arcsin(rm.ch / (2 * dSpacing * energy))) bragg = theta + 2 * pitch else: theta = bragg - 2 * pitch energy = rm.ch / (2 * dSpacing * np.sin(theta)) print('DCM.energy = {0:.3f} eV'.format(energy)) print('DCM.bragg = {0:.6f} deg'.format(np.degrees(bragg))) print('DCM.realThetaAngle = DCM.bragg - 2*VCM.pitch = {0:.6f} deg'.format( np.degrees(theta))) beamLine.dcm.energy = energy beamLine.dcm.bragg = bragg p = raycing.distance_xy(beamLine.vfm.center, beamLine.vcm.center) if heightVFM is not None: fixedExit = (heightVFM - beamLine.height - p * np.tan(2 * pitch)) * np.cos(2 * pitch) else: heightVFM = fixedExit / np.cos(2 * pitch) + \ beamLine.height + p * np.tan(2 * pitch) + 0.5 beamLine.heightVFM = heightVFM beamLine.dcm.fixedExit = fixedExit beamLine.dcm.cryst2perpTransl = \ beamLine.dcm.fixedExit/2./np.cos(beamLine.dcm.bragg) beamLine.dcm.get_orientation() print('DCM.pitch = {0:.6f} mrad'.format(beamLine.dcm.pitch*1e3)) print('DCM.roll = {0:.6f} mrad'.format(beamLine.dcm.roll*1e3)) print('DCM.yaw = {0:.6f} mrad'.format(beamLine.dcm.yaw*1e3)) print('DCM.z = {0:.3f}'.format(beamLine.dcm.center[2])) print('DCM.fixedExit = {0:.3f}'.format(fixedExit)) print('DCM.cryst2perpTransl = {0:.3f}'.format( beamLine.dcm.cryst2perpTransl)) print('DCM.dx = {0:.3f}'.format(beamLine.dcm.dx)) print('DCM.jack1.zCalib = {0:.3f}'.format(beamLine.dcm.jack1Calib)) print('DCM.jack2.zCalib = {0:.3f}'.format(beamLine.dcm.jack2Calib)) print('DCM.jack3.zCalib = {0:.3f}'.format(beamLine.dcm.jack3Calib)) p = raycing.distance_xy(beamLine.vfm.center, beamLine.fsm3.center) fsm3height = heightVFM - p * np.tan(2 * pitch) p = raycing.distance_xy( beamLine.vfm.center, (beamLine.xbpm4foils.center[0], beamLine.xbpm4foils.center[1])) heightXBPM4 = heightVFM - p * np.tan(2 * pitch) beamLine.xbpm4foils.select_aperture(nameDiagnFoil, heightXBPM4) print('beamLine.xbpm4foils.zActuator = {0:.3f}'.format( beamLine.xbpm4foils.zActuator)) beamLine.vfm.pitch = -pitch beamLine.vfm.center[2] = heightVFM - beamLine.vfm.hCylinder beamLine.vfm.set_jacks() # beamLine.vfm.yaw = 50e-6 beamLine.vfm.set_x_stages() beamLine.vfm.get_orientation() print('VFM.pitch = {0:.6f} mrad'.format(beamLine.vfm.pitch*1e3)) print('VFM.roll = {0:.6f} mrad'.format(beamLine.vfm.roll*1e3)) print('VFM.yaw = {0:.6f} mrad'.format(beamLine.vfm.yaw*1e3)) print('VFM.z = {0:.3f}'.format(beamLine.vfm.center[2])) print('VFM.R = {0:.0f}'.format(beamLine.vfm.R)) print('VFM.r = {0:.3f}'.format(beamLine.vfm.r)) print('VFM.dx = {0:.3f}'.format(beamLine.vfm.dx)) print('VFM.jack1.zCalib = {0:.3f}'.format(beamLine.vfm.jack1Calib)) print('VFM.jack2.zCalib = {0:.3f}'.format(beamLine.vfm.jack2Calib)) print('VFM.jack3.zCalib = {0:.3f}'.format(beamLine.vfm.jack3Calib)) print('VFM.tx1 = {0:.3f}'.format(beamLine.vfm.tx1[0])) print('VFM.tx2 = {0:.3f}'.format(beamLine.vfm.tx2[0])) beamLine.eh100To40Flange.center[2] = heightVFM print('eh100To40Flange.center[2] = {0:.3f}'.format( beamLine.eh100To40Flange.center[2])) beamLine.slitEH.opening[2] += heightVFM - beamLine.height beamLine.slitEH.opening[3] += heightVFM - beamLine.height beamLine.slitEH.set_optical_limits() print('fsm1.z = {0:.3f}'.format(beamLine.height)) print('fsm2.z = {0:.3f}'.format(fsm2height)) print('fsm3.z = {0:.3f}'.format(fsm3height)) print('fsm4.z = {0:.3f}'.format(heightVFM))
def align_beamline(beamLine, pitch=None, bragg=None, energy=9000., fixedExit=None, heightVFM=25, vfmR='auto'): p = raycing.distance_xy(beamLine.vfm.center, beamLine.sources[0].center) if pitch is None: sinPitch = beamLine.vfm.r * 1.5 / p pitch = math.asin(sinPitch) else: sinPitch = math.sin(pitch) if vfmR == 'auto': beamLine.vfm.R = p / sinPitch else: beamLine.vfm.R = vfmR fefm = beamLine.feFixedMask op = fefm.center[1] * aceptanceV / 2 * min(1, pitch / 2e-3) fefm.opening[2] = -op fefm.opening[3] = op beamLine.vcm.pitch = pitch p = raycing.distance_xy(beamLine.vcm.center, beamLine.sources[0].center) beamLine.vcm.R = 2. * p / sinPitch print('VCM.p = {0:.1f}'.format(p)) print('VCM.pitch = {0:.6f} mrad'.format(beamLine.vcm.pitch * 1e3)) print('VCM.roll = {0:.6f} mrad'.format(beamLine.vcm.roll * 1e3)) print('VCM.yaw = {0:.6f} mrad'.format(beamLine.vcm.yaw * 1e3)) print('VCM.z = {0:.3f}'.format(beamLine.vcm.center[2])) print('VCM.R = {0:.0f}'.format(beamLine.vcm.R)) p = raycing.distance_xy(beamLine.dmm.center, beamLine.vcm.center) beamLine.dmm.center[2] = beamLine.height + p * math.tan(2 * pitch) aML = beamLine.dmm.material[0] dSpacing = aML.d print(u'DMM.dSpacing = {0:.6f} angstrom'.format(dSpacing)) if bragg is None: theta = aML.get_Bragg_angle(energy) -\ aML.get_dtheta_symmetric_Bragg(energy) # theta = np.radians(1.05) bragg = theta + 2 * pitch else: theta = bragg - 2 * pitch energy = rm.ch / (2 * dSpacing * math.sin(theta)) print('DMM.energy = {0:.3f} eV'.format(energy)) print('DMM.bragg = {0:.6f} deg'.format(math.degrees(bragg))) print('DMM.realThetaAngle = DMM.bragg - 2*VCM.pitch = {0:.6f} deg'.format( math.degrees(theta))) beamLine.dmm.energy = energy beamLine.dmm.bragg = bragg p = raycing.distance_xy(beamLine.vfm.center, beamLine.vcm.center) if heightVFM is not None: fixedExit = (heightVFM - beamLine.height - p * math.tan(2 * pitch)) * \ math.cos(2 * pitch) else: heightVFM = fixedExit / math.cos(2 * pitch) + \ beamLine.height + p * math.tan(2 * pitch) + 0.2 beamLine.heightVFM = heightVFM beamLine.dmm.fixedExit = fixedExit beamLine.dmm.cryst2perpTransl =\ beamLine.dmm.fixedExit/2./math.cos(beamLine.dmm.bragg) print('DMM.pitch = {0:.6f} mrad'.format(beamLine.dmm.pitch * 1e3)) print('DMM.roll = {0:.6f} mrad'.format(beamLine.dmm.roll * 1e3)) print('DMM.yaw = {0:.6f} mrad'.format(beamLine.dmm.yaw * 1e3)) print('DMM.z = {0:.3f}'.format(beamLine.dmm.center[2])) print('DMM.fixedExit = {0:.3f}'.format(fixedExit)) print('DMM.cryst2perpTransl = {0:.3f}'.format( beamLine.dmm.cryst2perpTransl)) p = raycing.distance_xy( beamLine.vfm.center, (beamLine.slitAfterDCM.center[0], beamLine.slitAfterDCM.center[1])) slitHeight = heightVFM - p * math.tan(2 * pitch) dz = beamLine.slitAfterDCM.opening[3] - beamLine.slitAfterDCM.opening[2] beamLine.slitAfterDCM.opening[2] = slitHeight - beamLine.height - dz / 2 beamLine.slitAfterDCM.opening[3] = slitHeight - beamLine.height + dz / 2 beamLine.slitAfterDCM.set_optical_limits() p = raycing.distance_xy(beamLine.vfm.center, beamLine.fsmDCM.center) fsmHeight = heightVFM - p * math.tan(2 * pitch) print('fsmDCM.z = {0:.3f}'.format(fsmHeight)) beamLine.vfm.pitch = -pitch beamLine.vfm.center[2] = heightVFM # - beamLine.vfm.hCylinder print('VFM.pitch = {0:.6f} mrad'.format(beamLine.vfm.pitch * 1e3)) print('VFM.roll = {0:.6f} mrad'.format(beamLine.vfm.roll * 1e3)) print('VFM.yaw = {0:.6f} mrad'.format(beamLine.vfm.yaw * 1e3)) print('VFM.z = {0:.3f}'.format(beamLine.vfm.center[2])) print('VFM.R = {0:.0f}'.format(beamLine.vfm.R)) print('VFM.r = {0:.3f}'.format(beamLine.vfm.r)) dz = beamLine.slitAfterVFM.opening[3] - beamLine.slitAfterVFM.opening[2] beamLine.slitAfterVFM.opening[2] = heightVFM - beamLine.height - dz / 2 beamLine.slitAfterVFM.opening[3] = heightVFM - beamLine.height + dz / 2 beamLine.slitAfterVFM.set_optical_limits() p = raycing.distance_xy(beamLine.vfm.center, beamLine.sources[0].center) q = 1. / (2 * np.sin(pitch) / beamLine.vfm.r - 1. / p) qr = raycing.distance_xy(beamLine.fsmSample.center, beamLine.vfm.center) beamLine.spotSizeH = abs(1. - qr / q) * p * aceptanceH qr = raycing.distance_xy( (beamLine.slitEH.center[0], beamLine.slitEH.center[1]), beamLine.vfm.center) s = abs(1. - qr / q) * p * aceptanceH / 2 beamLine.slitEH.opening[0] = -s * 1.2 beamLine.slitEH.opening[1] = s * 1.2 dz = beamLine.slitEH.opening[3] - beamLine.slitEH.opening[2] beamLine.slitEH.opening[2] = heightVFM - beamLine.height - dz / 2 beamLine.slitEH.opening[3] = heightVFM - beamLine.height + dz / 2 beamLine.slitEH.set_optical_limits()
def align_beamline(beamLine, pitch=None, bragg=None, energy=9000., fixedExit=None, heightVFM=42.79, vfmR='auto'): p = raycing.distance_xy(beamLine.vfm.center, beamLine.sources[0].center) if pitch is None: sinPitch = beamLine.vfm.r * 1.5 / p pitch = math.asin(sinPitch) else: sinPitch = math.sin(pitch) if vfmR == 'auto': beamLine.vfm.R = p / sinPitch else: beamLine.vfm.R = vfmR fefm = beamLine.feFixedMask op = fefm.center[1] * aceptanceV / 2 * min(1, pitch/2e-3) fefm.opening[2] = -op fefm.opening[3] = op beamLine.vcm.pitch = pitch p = raycing.distance_xy(beamLine.vcm.center, beamLine.sources[0].center) beamLine.vcm.R = 2. * p / sinPitch print('VCM.p = {0:.1f}'.format(p)) print('VCM.pitch = {0:.6f} mrad'.format(beamLine.vcm.pitch*1e3)) print('VCM.roll = {0:.6f} mrad'.format(beamLine.vcm.roll*1e3)) print('VCM.yaw = {0:.6f} mrad'.format(beamLine.vcm.yaw*1e3)) print('VCM.z = {0:.3f}'.format(beamLine.vcm.center[2])) print('VCM.R = {0:.0f}'.format(beamLine.vcm.R)) p = raycing.distance_xy(beamLine.dcm.center, beamLine.vcm.center) beamLine.dcm.center[2] = beamLine.height + p*math.tan(2*pitch) aCrystal = beamLine.dcm.material[0] dSpacing = aCrystal.d print('DCM.dSpacing = {0:.6f} angsrom'.format(dSpacing)) if bragg is None: theta = math.asin(rm.ch / (2*dSpacing*energy)) -\ aCrystal.get_dtheta_symmetric_Bragg(energy) bragg = theta + 2*pitch else: theta = bragg - 2*pitch energy = rm.ch / (2*dSpacing*math.sin(theta)) print('DCM.energy = {0:.3f} eV'.format(energy)) print('DCM.bragg = {0:.6f} deg'.format(math.degrees(bragg))) print('DCM.realThetaAngle = DCM.bragg - 2*VCM.pitch = {0:.6f} deg'.format( math.degrees(theta))) beamLine.dcm.energy = energy beamLine.dcm.bragg = bragg p = raycing.distance_xy(beamLine.vfm.center, beamLine.vcm.center) if heightVFM is not None: fixedExit = (heightVFM - beamLine.height - p * math.tan(2 * pitch)) * \ math.cos(2 * pitch) else: heightVFM = fixedExit / math.cos(2 * pitch) + \ beamLine.height + p * math.tan(2 * pitch) + 0.2 beamLine.heightVFM = heightVFM beamLine.dcm.fixedExit = fixedExit beamLine.dcm.cryst2perpTransl =\ beamLine.dcm.fixedExit/2./math.cos(beamLine.dcm.bragg) print('DCM.pitch = {0:.6f} mrad'.format(beamLine.dcm.pitch*1e3)) print('DCM.roll = {0:.6f} mrad'.format(beamLine.dcm.roll*1e3)) print('DCM.yaw = {0:.6f} mrad'.format(beamLine.dcm.yaw*1e3)) print('DCM.z = {0:.3f}'.format(beamLine.dcm.center[2])) print('DCM.fixedExit = {0:.3f}'.format(fixedExit)) print('DCM.cryst2perpTransl = {0:.3f}'.format( beamLine.dcm.cryst2perpTransl)) p = raycing.distance_xy( beamLine.vfm.center, (beamLine.slitAfterDCM.center[0], beamLine.slitAfterDCM.center[1])) slitHeight = heightVFM - p * math.tan(2 * pitch) dz = beamLine.slitAfterDCM.opening[3] - beamLine.slitAfterDCM.opening[2] beamLine.slitAfterDCM.opening[2] = slitHeight - beamLine.height - dz/2 beamLine.slitAfterDCM.opening[3] = slitHeight - beamLine.height + dz/2 beamLine.slitAfterDCM.set_optical_limits() p = raycing.distance_xy(beamLine.vfm.center, beamLine.fsmDCM.center) fsmHeight = heightVFM - p * math.tan(2 * pitch) print('fsmDCM.z = {0:.3f}'.format(fsmHeight)) beamLine.vfm.pitch = -pitch beamLine.vfm.center[2] = heightVFM # - beamLine.vfm.hCylinder print('VFM.pitch = {0:.6f} mrad'.format(beamLine.vfm.pitch*1e3)) print('VFM.roll = {0:.6f} mrad'.format(beamLine.vfm.roll*1e3)) print('VFM.yaw = {0:.6f} mrad'.format(beamLine.vfm.yaw*1e3)) print('VFM.z = {0:.3f}'.format(beamLine.vfm.center[2])) print('VFM.R = {0:.0f}'.format(beamLine.vfm.R)) print('VFM.r = {0:.3f}'.format(beamLine.vfm.r)) dz = beamLine.slitAfterVFM.opening[3] - beamLine.slitAfterVFM.opening[2] beamLine.slitAfterVFM.opening[2] = heightVFM - beamLine.height - dz/2 beamLine.slitAfterVFM.opening[3] = heightVFM - beamLine.height + dz/2 beamLine.slitAfterVFM.set_optical_limits() p = raycing.distance_xy(beamLine.vfm.center, beamLine.sources[0].center) q = 1./(2 * np.sin(pitch)/beamLine.vfm.r - 1./p) qr = raycing.distance_xy(beamLine.fsmSample.center, beamLine.vfm.center) beamLine.spotSizeH = abs(1. - qr / q) * p * aceptanceH qr = raycing.distance_xy( (beamLine.slitEH.center[0], beamLine.slitEH.center[1]), beamLine.vfm.center) s = abs(1. - qr / q) * p * aceptanceH / 2 beamLine.slitEH.opening[0] = -s * 1.2 beamLine.slitEH.opening[1] = s * 1.2 dz = beamLine.slitEH.opening[3] - beamLine.slitEH.opening[2] beamLine.slitEH.opening[2] = heightVFM - beamLine.height - dz/2 beamLine.slitEH.opening[3] = heightVFM - beamLine.height + dz/2 beamLine.slitEH.set_optical_limits()