#!/usr/bin/env python #*-----------------------------------------------------------------------* #| | #| Copyright (c) 2019 by Paul Scherrer Institute (http://www.psi.ch) | #| | #| Author Thierry Zamofing (thierry.zamofing@psi.ch) | #*-----------------------------------------------------------------------* ''' generate .subs and _startup.script files mode bits: 0x001: genYAML() 0x002: genIOC() 0x004: genLauncher() Long Doc''' from __future__ import print_function import logging, sys, os, json import string class Generate: yamlParam={ # ioc : ( host , port , ver , arch , osys , osys_id , # 'SAR-CSSU-EXPMX1' : ('SAR-CSSU-EXPMX1' , 50001 , '3.14.12' , 'moxa42-armv6l' , 'moxa42-armv6l' , 'moxa42-armv6l' , ) , 'SAR-CPPM-EXPMX1' : ('SAR-CPPM-EXPMX1' , 50001 , '7.0.7' , 'eldk42-ppc4xxFP' , 'eldk42-ppc4xxFP' , 'eldk42-ppc4xxFP' , ) , 'SAR-CPPM-EXPMX2' : ('SAR-CPPM-EXPMX2' , 50001 , '7.0.7' , 'eldk42-ppc4xxFP' , 'eldk42-ppc4xxFP' , 'eldk42-ppc4xxFP' , ) , 'SAR-CPPM-EXPMX3' : ('SAR-CPPM-EXPMX3' , 50001 , '7.0.7' , 'eldk42-ppc4xxFP' , 'eldk42-ppc4xxFP' , 'eldk42-ppc4xxFP' , ) , 'SAR-CPPM-EXPMX4' : ('SAR-CPPM-EXPMX4' , 50001 , '7.0.7' , 'eldk42-ppc4xxFP' , 'eldk42-ppc4xxFP' , 'eldk42-ppc4xxFP' , ) , 'SARES30-CPCL-MCSSMX' : ('saresc-vserv-01' , 50001 , '7.0.7' , 'x86_64' , 'RHEL8' , 'rhel' , ) , } iocSmarAct={ 'SARES30-CPCL-MCSSMX': { 'port':'MCS', 'host':'129.129.244.32', # 00:04:a3:a2:71:35, MCS0060 Serial: 3762 'prefix':'SARES30-SMX', 'loc':'EH.057 MobRack', 'fmt':'{{{PORT:5},{S:14},{M:6},{ADDR:>4},{DESC:14},{DIR:3},{VELO:4},{DHLM:>6},{DLLM:>6},{EGU:4},{PTYP:4},{RTRY:4}}}\n', 'motLst':( # dir: Pos:0 Neg:1 ( 'DESC' , 'M' , 'ADDR', 'DHLM', 'DLLM', 'DIR', 'EGU', 'PTYP'), ('COLLI:TX' , 'MCS1' , 0 , 12 , -10 , 1 , 'mm' , 'S' ) , ('COLLI:TY' , 'MCS2' , 1 , 12 , -10 , 1 , 'mm' , 'S' ) , ('Motor3' , 'MCS3' , 2 , 10 , -10 , 0 , 'mm' , 'S' ) , ('POSTTUBE:TX1', 'MCS4' , 3 , 10 , -10 , 0 , 'mm' , 'S' ) , ('POSTTUBE:TX2', 'MCS5' , 4 , 10 , -10 , 0 , 'mm' , 'S' ) , ('POSTTUBE:TY1', 'MCS6' , 5 , 15 , -20 , 0 , 'mm' , 'S' ) , ('POSTTUBE:TY2', 'MCS7' , 6 , 15 , -20 , 0 , 'mm' , 'S' ) , ('POSTTUBE:TZ' , 'MCS8' , 7 , 10 , -10 , 1 , 'mm' , 'S' ) , ('Motor9' , 'MCS9' , 8 , 10 , -10 , 0 , 'mm' , 'S' ) , ('SLITS:X1' , 'MCS10', 9 , 10 , -10 , 1 , 'mm' , 'S' ) , ('SLITS:X2' , 'MCS11', 10 , 10 , -10 , 1 , 'mm' , 'S' ) , ('SLITS:Y1' , 'MCS12', 11 , 10 , -10 , 1 , 'mm' , 'S' ) , ('SLITS:Y2' , 'MCS13', 12 , 10 , -10 , 1 , 'mm' , 'S' ) , ('unused' , 'MCS14', 13 , 10 , -10 , 0 , 'mm' , 'S' ) , ('unused' , 'MCS15', 14 , 10 , -10 , 0 , 'mm' , 'S' ) , ), } } iocPowerBrick={ # HOST runScript 'SAR-CPPM-EXPMX1':{ 'port':'PPMAC', 'prefix':'SAR-EXPMX', 'loc':'EH.057 MobRack', 'fmt': '{{{P:10},{M:10},{ADDR:4},{DESC:19},{DIR:3},{VELO:4},{HVEL:4},{MRES:5},{PREC:4},{EGU:4}}}\n', 'motLst':( ( 'DESC' , 'M' , 'ADDR' , 'DIR' , 'VELO' , 'HVEL' , 'MRES' , 'PREC' , 'EGU' ) , ( '"Sample F-Trans Y"' , 'MOT_FY' , 1 , 0 , 16 , 2 , 0.001 , 4 , 'mm' ) , ( '"Sample F-Trans X"' , 'MOT_FX' , 2 , 0 , 16 , 2 , 0.001 , 4 , 'mm' ) , ( '"Sample C-Trans Y"' , 'MOT_CY' , 3 , 0 , 12 , 4 , 0.001 , 4 , 'mm' ) , ( '"Sample C-Trans X"' , 'MOT_CX' , 4 , 0 , 2 , 2 , 0.001 , 4 , 'mm' ) , ( '"Sample C-Trans Z"' , 'MOT_CZ' , 5 , 0 , 2 , 2 , 0.001 , 4 , 'mm' ) , ( '"Interfero Y"' , 'ENC_FY' , 6 , 0 , 2 , 2 , 0.001 , 4 , 'mm' ) , ( '"Interfero X"' , 'ENC_FX' , 7 , 0 , 2 , 2 , 0.001 , 4 , 'mm' ) , ), }, 'SAR-CPPM-EXPMX2':{ 'port':'PPMAC', 'prefix':'SAR-EXPMX', 'loc':'EH.057 MobRack', 'fmt': '{{{P:10},{M:10},{ADDR:4},{DESC:12},{DIR:3},{VELO:4},{HVEL:4},{MRES:5},{PREC:4},{EGU:4}}}\n', 'motLst':( ( 'DESC' , 'M' , 'ADDR' , 'DIR' , 'VELO' , 'HVEL' , 'MRES' , 'PREC' , 'EGU' ) , ( '"Wedge 1"' , 'MOT_WEDGE1' , 1 , 0 , 1. , .5 , 0.001 , 3 , 'mm' ) , ( '"Wedge 2"' , 'MOT_WEDGE2' , 2 , 0 , 1. , .5 , 0.001 , 3 , 'mm' ) , ( '"Wedge 3"' , 'MOT_WEDGE3' , 3 , 0 , 1. , .5 , 0.001 , 3 , 'mm' ) , ( '"Wedge 4"' , 'MOT_WEDGE4' , 4 , 0 , 1. , .5 , 0.001 , 3 , 'mm' ) , ( '"Wedge X"' , 'MOT_WEDGEX' , 9 , 1 , 1. , .5 , 0.001 , 3 , 'mm' ) , ( '"Wedge Y"' , 'MOT_WEDGEY' , 10 , 0 , 1. , .5 , 0.001 , 3 , 'mm' ) , ( '"Wedge A"' , 'MOT_WEDGEA' , 11 , 0 , 1. , .5 , 0.001 , 3 , 'mm' ) , ( '"Wedge B"' , 'MOT_WEDGEB' , 12 , 1 , 1. , .5 , 0.001 , 3 , 'mm' ) , ( '"Backlight"' , 'MOT_BLGT' , 5 , 1 , 40E3 , 20E3 , 1 , 0 , 'usr' ) , ( '"Cryojet"' , 'MOT_CRYO' , 6 , 1 , 10. , 5. , 0.001 , 3 , 'mm' ) , ), }, 'SAR-CPPM-EXPMX3':{ 'port':'PPMAC', 'prefix':'SAR-EXPMX', 'loc':'EH.057 MobRack', 'fmt': '{{{P:10},{M:10},{ADDR:4},{DESC:13},{DIR:3},{VELO:4},{MRES:5},{PREC:4},{EGU:4}}}\n', 'motLst':( ( 'DESC' , 'M' , 'ADDR' , 'DIR' , 'VELO' , 'MRES' , 'PREC' , 'EGU' ) , ( '"Girder 1"' , 'MOT_GIR_1' , 1 , 0 , 40 , 0.001 , 3 , 'deg' ) , ( '"Girder 2"' , 'MOT_GIR_2' , 2 , 0 , 40 , 0.001 , 3 , 'deg' ) , ( '"Girder 3"' , 'MOT_GIR_3' , 3 , 0 , 40 , 0.001 , 3 , 'deg' ) , ( '"Girder 4"' , 'MOT_GIR_4' , 4 , 0 , 40 , 0.001 , 3 , 'deg' ) , ( '"Girder 5"' , 'MOT_GIR_5' , 5 , 0 , 40 , 0.001 , 3 , 'deg' ) , ( '"Girder X"' , 'MOT_GIR_X' , 9 , 0 , 40 , 0.001 , 3 , 'mm' ) , ( '"Girder Y"' , 'MOT_GIR_Y' , 10 , 0 , 40 , 0.001 , 3 , 'mm' ) , ( '"Girder U"' , 'MOT_GIR_U' , 11 , 0 , 40 , 0.001 , 3 , 'mrad' ) , ( '"Girder V"' , 'MOT_GIR_V' , 12 , 0 , 40 , 0.001 , 3 , 'mrad' ) , ( '"Girder W"' , 'MOT_GIR_W' , 13 , 0 , 40 , 0.001 , 3 , 'mrad' ) , ( '"Detector Z"' , 'MOT_DET_Z' , 6 , 1 , 4 , 0.001 , 3 , 'mm' ) , ), }, 'SAR-CPPM-EXPMX4':{ 'port':'PPMAC', 'prefix':'SAR-EXPMX', 'loc':'EH.057 MobRack', 'fmt': '{{{P:10},{M:10},{ADDR:4},{DESC:27},{DIR:3},{VELO:4},{MRES:5},{PREC:4},{EGU:4}}}\n', 'motLst':( ('DESC', 'M', 'ADDR', 'DIR', 'VELO', 'MRES', 'PREC', 'EGU'), # desc , m , addr , dir , velo , hvel , accl , jar , mres , prec , egu , dhlm , dllm , # NOT YET ANY MOTOR ), }, } tplYaml='''\ ioc_host: {host} ioc_port: {port} epics_version: {ver} cpu_architecture: {arch} os: {osys} os_id: {osys_id} ''' # /home/zamofing_t/Documents/doc-ext/SmaractMCS/MCS2PositionerTypes.pdf Positioner Types Cross Reference lutPSENS={ # abrev_(MCS2code, MCS1code) 'S':(300,1),'SD':(301,21),'SP':(302,5),'SC':(303,6),'SCD':(304,24),'SC500':(307,18),'SR20':(309,8), 'SR':(312,2),'SR2':(313,23),'SR77':(316,20),'SR120':(320,37),'G605DS':(325,48),'G775DS':(328,49), 'LE':(342,43),'LED':(343,44),'L':(345,41),'LD':(346,42),'LC':(348,38),'LCD':(349,40),'LR':(354,39), 'M':(357,9),'MD':(358,32),'GD':(363,11),'GE':(366,12),'G605L':(381,50),'G775L':(383,51),'G605LE':(387,53), 'G775LE':(389,54),'G605LC':(396,57),'G775LC':(398,58),'G775LE':(389,54), } tplMcsCtrl='''\ ################################################################### # DO NOT EDIT: Generated with epics_ioc_modules/ESB_MX/generate.py # This is the IOC {ioc} on {ioc_host}:{ioc_port} ################################################################## epicsEnvSet("ENGINEER", "zamofing_t") epicsEnvSet("LOCATION", "{loc}") ###### require modules ############ # motorSmarAct community driver # smarActMot PSI templates and other files require motorSmarAct require smarActMot require ESB_MX ###### initialize device ############ drvAsynIPPortConfigure("asyn{port}", "{host}:5000", 0, 0, 0) #ctrlPort, asynPort, number of axes, active poll period (ms), idle poll period ms), [default debug lvl] MCSCreateController("{port}", "asyn{port}", {num_ax}, 100, 1000, 0x00) ''' mcsSubsHdr='''\ file asyn.template {{{{P={prefix}, PORT=asyn{port}}}}} ##### MCS file $(smarActMot_DIR)/db/MCS_axis.template {{ pattern ''' tplPwrBrkCtrl='''\ ########################################## # DO NOT EDIT: Generated with generate.py # This is the IOC on host {ioc} ########################################## # PPMAC responsible: Thierry Zamofing ########################################## ###### initialize device ############ require PB_COMMON {req} #powerPmacCreateController(, , ) powerPmacCreateController("{port}", 200, 1000) ###### initialize axes ############ ''' tplPwrBrkAxis='''\ powerPmacCreateAxis({PORT}, {ADDR}) ''' tplEXPMX1=''' ###### initialize EVR ############ # https://git.psi.ch/epics_driver_modules/mrfioc2 require mrfioc2 runScript $(mrfioc2_DIR)/mrfioc2_evr-PCIe.cmd, "DEVICE=EVR0,EVR_SUBS=$(ESB_MX_DIR)/db/evr_PCIe-300DC.subs,EVR_DOMAIN=0x2,EVR_BUS=0x21,SYS=SAR-EXPMX" ###### initialize EVR data buffer ############ # https://git.psi.ch/epics_driver_modules/mrfioc2_regDev require mrfioc2_regDev runScript $(mrfioc2_regDev_DIR)/mrfioc2_regDev_pulseID_RX.cmd, "DEVICE=EVR0,SYS=SAR-EXPMX" require PB_EXTRA dbLoadRecords("$(PB_EXTRA_TEMPLATES)motorStatus.db" "SYS=SAR-EXPMX, PORT=PPMAC, M=MOT_FY, M_NO=1") dbLoadRecords("$(PB_EXTRA_TEMPLATES)motorStatus.db" "SYS=SAR-EXPMX, PORT=PPMAC, M=MOT_FX, M_NO=2") dbLoadRecords("$(PB_EXTRA_TEMPLATES)motorStatus.db" "SYS=SAR-EXPMX, PORT=PPMAC, M=MOT_CY, M_NO=3") dbLoadRecords("$(PB_EXTRA_TEMPLATES)motorStatus.db" "SYS=SAR-EXPMX, PORT=PPMAC, M=MOT_CX, M_NO=4") dbLoadRecords("$(PB_EXTRA_TEMPLATES)motorStatus.db" "SYS=SAR-EXPMX, PORT=PPMAC, M=MOT_CZ, M_NO=5") dbLoadRecords("$(PB_EXTRA_TEMPLATES)killOne.db" "SYS=SAR-EXPMX, PORT=PPMAC, M=MOT_FY, M_NO=1") dbLoadRecords("$(PB_EXTRA_TEMPLATES)killOne.db" "SYS=SAR-EXPMX, PORT=PPMAC, M=MOT_FX, M_NO=2") dbLoadRecords("$(PB_EXTRA_TEMPLATES)killOne.db" "SYS=SAR-EXPMX, PORT=PPMAC, M=MOT_CY, M_NO=3") dbLoadRecords("$(PB_EXTRA_TEMPLATES)killOne.db" "SYS=SAR-EXPMX, PORT=PPMAC, M=MOT_CX, M_NO=4") dbLoadRecords("$(PB_EXTRA_TEMPLATES)killOne.db" "SYS=SAR-EXPMX, PORT=PPMAC, M=MOT_CZ, M_NO=5") ''' tplEXPMX2=''' #powerPmacCreateVirtualAxis(, , , ,, , , ,1: motLst=v['motLst'][1:] else: motLst=tuple() param= {k: v[k] for k in {'port','prefix','loc'}} param['ioc']=ioc param['idx']=ioc[-1] param['num_ax']=len(motLst) param['req']='require ESB_MX\n\n! $(gpasciiCommander_DIR)/gpasciiCommander --path $(ESB_MX_DIR) $(ESB_MX_DIR)/{prefix}{idx}.cfg'.format(**param) #print(param) fn=f'gen/ioc/{ioc}_startup.script' print('generate '+fn+' ...') fh_ss=open(fn,'w') fn=f'gen/ioc/{ioc}_gen.subs' # with a name _* the .subs file is recognize by the 'ioc install' tool print('generate '+fn+' ...') fh_sb=open(fn,'w') #fn=f'gen/ioc/cfg/{ioc}_sr.req' #print('generate '+fn+' ...') #fh_sr=open(fn,'w') fh_ss.write(tplCtrl.format(**param)) fh_sb.write(subsHdr.format(**param)) port=param['port'] prefix=param['prefix'] motPar=dict(zip(hdr, hdr)) motPar['PORT']='PORT' motPar['P']='P' fh_sb.write(fmt.format(**motPar)) for motPar in motLst: motPar=dict(zip(hdr, motPar)) motPar['PORT']=v['port'] motPar['P']=v['prefix'] fh_sb.write(fmt.format(**motPar)) if motPar['ADDR']<=8: fh_ss.write(tplAxis.format(**motPar)) fh_sb.write('}\n\n') if ioc=='SAR-CPPM-EXPMX1': fh_ss.write(Generate.tplEXPMX1) elif ioc=='SAR-CPPM-EXPMX2': fh_ss.write(Generate.tplEXPMX2) elif ioc=='SAR-CPPM-EXPMX3': fh_ss.write(Generate.tplEXPMX3) fh_ss.close() fh_sb.close() def genSmarActIOC(self): tplCtrl=Generate.tplMcsCtrl #tplAxis=Generate.tplMcsAxis #tplAxSR=Generate.tplMcsAxisSaveRestore subsHdr=Generate.mcsSubsHdr lutPSENS=Generate.lutPSENS os.makedirs('gen/ioc/cfg/',exist_ok=True) for ioc,v in Generate.iocSmarAct.items(): # fh_ss startup script # fh_sb substitution # fh_sr save restore fmt=' '+v['fmt'] hdr=v['motLst'][0] if len(v['motLst'])>1: motLst=v['motLst'][1:] else: motLst=tuple() param= {k: v[k] for k in {'port','host','prefix','loc'}} try: ioc_host,ioc_port=Generate.yamlParam[ioc][:2] except KeyError as e: _log.warning(repr(e)+': skipped');continue param['ioc']=ioc param['ioc_host']=ioc_host param['ioc_port']=ioc_port param['num_ax']=len(motLst) #print(param) fn=f'gen/ioc/{ioc}_startup.script' print('generate '+fn+' ...') fh_ss=open(fn,'w') fn=f'gen/ioc/{ioc}_gen.subs' # with a name _* the .subs file is recognize by the 'ioc install' tool print('generate '+fn+' ...') fh_sb=open(fn,'w') #fn=f'gen/ioc/cfg/{ioc}_sr.req' #print('generate '+fn+' ...') #fh_sr=open(fn,'w') fh_ss.write(tplCtrl.format(**param)) fh_sb.write(subsHdr.format(**param)) h=hdr+('PORT','S','VELO','RTRY') motPar=dict(zip(h, h)) fh_sb.write(fmt.format(**motPar)) for motPar in motLst: motPar=dict(zip(hdr, motPar)) try: motPar['PTYP']=lutPSENS[motPar['PTYP']][1] #idx1 is for MCS1 except KeyError as e: if motPar['PTYP']!=0: _log.info(f'{motPar["PTYP"]} not in lookup table') motPar['PORT']=v['port'] motPar['S']=v['prefix'] motPar['VELO']=2 motPar['RTRY']=1 fh_sb.write(fmt.format(**motPar)) #fh_ss.write(tplAxis.format(**motPar)) #fh_sr.write(tplAxSR.format(**motPar)) fh_sb.write('}\n\n') fh_ss.close() fh_sb.close() #fh_sr.close() #fn='gen/ioc/asyn.template' #print('generate '+fn+' ...') #with open(fn,'w') as fh: # fh.write(Generate.tpl_asyn) if __name__=='__main__': def parse_args(): import argparse (h, t)=os.path.split(sys.argv[0]);cmd='\n '+(t if len(h)>20 else sys.argv[0])+' ' #print(sys.argv,h,t) exampleCmd=('', '-m0xf -v0' ) epilog=__doc__+'\nExamples:'+''.join(map(lambda s:cmd+s, exampleCmd))+'\n' parser = argparse.ArgumentParser(epilog=epilog,formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('-m', '--mode', type=lambda x: int(x,0), help='mode bits', default=0xff) args = parser.parse_args() #print(args) obj=Generate() if args.mode&0x1: obj.genYAML() if args.mode&0x2: obj.genIOC() if args.mode&0x4: obj.genLauncher() parse_args()