合并2个程序

main
chaopower 2023-07-05 17:15:46 +08:00
parent 95d012f575
commit f9a47149b5
10 changed files with 403 additions and 55 deletions

93
client.py 100644
View File

@ -0,0 +1,93 @@
import socket
import struct
import json
import os
import PySimpleGUI as sg
def recvdata(conn, filepath):
header_size = struct.unpack('i', conn.recv(4))[0]
header_bytes = conn.recv(header_size)
header_json = header_bytes.decode('utf-8')
header_dic = json.loads(header_json)
content_len = header_dic['contentlen']
content_name = header_dic['contentname']
recv_len = 0
pdf = os.path.join(filepath, content_name)
with open(pdf, 'wb') as file:
while recv_len < content_len:
correntrecv = conn.recv(1024 * 1000)
file.write(correntrecv)
recv_len += len(correntrecv)
def senddata(conn, path, select_type):
name = os.path.basename(os.path.realpath(path))
try:
with open(path, 'rb') as file:
content = file.read()
headerdic = dict(
contentlen=len(content),
contentname=name,
select_type=select_type
)
headerjson = json.dumps(headerdic)
headerbytes = headerjson.encode('utf-8')
headersize = len(headerbytes)
conn.send(struct.pack('i', headersize))
conn.send(headerbytes)
conn.sendall(content)
except ConnectionResetError:
print('不存在这个文件!')
def connect():
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
dest_ip = '192.168.11.121'
dest_port = int(8190)
client.connect((dest_ip, dest_port))
return client
def transclient(sendfile, resfile, select_type):
conn = connect()
senddata(conn, sendfile, select_type)
recvdata(conn, resfile)
def make_gui():
while True:
layout = [
[sg.Text('选择排样程序')],
[sg.Radio('T7', 'layout', key='t7', default=True), sg.Radio('nova', 'layout', key='nova'),
sg.Radio('Xplus', 'layout', key='xplus')],
[
sg.Text('导入排样excel')],
[
sg.Input(key='_FILE1_'), sg.FileBrowse()],
[
sg.Text('生成排样位置')],
[
sg.Input(key='_FILE2_'), sg.FolderBrowse()],
[
sg.OK(), sg.Cancel()]]
window = sg.Window('解码排样测试程序', layout)
event, values = window.Read()
if event == 'OK':
if values['nova']:
select_type = 'nova'
elif values['xplus']:
select_type = 'xplus'
else:
select_type = 't7'
transclient(values['_FILE1_'], os.path.join(values['_FILE2_'], select_type))
sg.Popup('排样成功!')
else:
window.Close()
break
if __name__ == '__main__':
# respath = 'result'
# transclient(os.path.join('example', '0520_T7_1.xlsx'), respath)
make_gui()

Binary file not shown.

Binary file not shown.

View File

@ -4,6 +4,11 @@ import json
import os import os
from datetime import datetime from datetime import datetime
from tools.common import basedir
from tools.t7 import AutoLayout as T7
from tools.novaplus import AutoLayout as NovaPlus
def recvdata(conn, path): def recvdata(conn, path):
""" """
@ -18,15 +23,16 @@ def recvdata(conn, path):
header_dic = json.loads(header_json) header_dic = json.loads(header_json)
content_len = header_dic['contentlen'] content_len = header_dic['contentlen']
content_name = header_dic['contentname'] content_name = header_dic['contentname']
select_type = header_dic['select_type']
recv_len = 0 recv_len = 0
fielpath = os.path.join(path, '%s_%s' %(datetime.now().strftime("%m%d%H%M"), content_name)) fielpath = os.path.join(path, '%s_%s' % (datetime.now().strftime("%m%d%H%M"), content_name))
file = open(fielpath, 'wb') file = open(fielpath, 'wb')
while recv_len < content_len: while recv_len < content_len:
correntrecv = conn.recv(1024 * 1000) correntrecv = conn.recv(1024 * 1000)
file.write(correntrecv) file.write(correntrecv)
recv_len += len(correntrecv) recv_len += len(correntrecv)
file.close() file.close()
return fielpath return fielpath, select_type
def senddata(conn, path, message=None): def senddata(conn, path, message=None):
@ -57,4 +63,27 @@ def senddata(conn, path, message=None):
conn.sendall(path.encode('utf-8')) conn.sendall(path.encode('utf-8'))
def server():
myserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
adrss = ("", 8191)
myserver.bind(adrss)
myserver.listen(5)
while True:
try:
myclient, adddr = myserver.accept()
recv_content, select_type = recvdata(myclient, os.path.join(basedir, 'example'))
if select_type == 'nova':
layout = NovaPlus(recv_content, data_limit=800)
elif select_type == 'xplus':
layout = NovaPlus(recv_content, data_limit=400)
else:
layout = T7(recv_content, data_limit=1520)
outputpath = layout.run()
senddata(myclient, outputpath)
except Exception as e:
print(e)
continue
if __name__ == '__main__':
server()

20
tools/common.py 100644
View File

@ -0,0 +1,20 @@
import os
import logging
basedir = os.path.dirname(os.path.realpath(__file__))
def log(name):
"""
日志
:param name:
:return: 返回logger对象
"""
logger = logging.getLogger('main')
logpath = os.path.join(basedir, 'log', name + '.log.txt')
logfile = logging.FileHandler(logpath, mode='w')
logfomat = logging.Formatter('%(message)s\t%(asctime)s')
logfile.setFormatter(logfomat)
logfile.setLevel(logging.DEBUG)
logger.addHandler(logfile)
return logger

243
tools/novaplus.py 100644
View File

@ -0,0 +1,243 @@
import os
import socket
import pandas as pd
from collections import defaultdict
from datetime import datetime
import time
import logging
import os
from .common import basedir, log
class AutoLayout:
"""
自动化派样
"""
def __init__(self, path, output=basedir, data_limit=1600):
self.path = path
self.output = output
self.data_limit = data_limit
self.index_assignments = defaultdict(list)
# 芯片数量量大小
self.chip_size = dict()
# 芯片是否极致
self.chip_type = dict()
# 芯片barcode
self.chip_barcode_recode = defaultdict(set)
# 芯片原始数据读取
self.ori_data = self.read_excel()
# 当前锚芯片
self.loc_chip_num = 1
# 芯片 文库计数
self.chip_lib_type = defaultdict(dict)
self.logger = log(os.path.basename(f'{path}.txt'))
self.return_log = list()
def read_excel(self):
"""
原始数据处理
:return:
"""
merge = pd.read_excel(self.path, None)
ori_data = dict()
for name, sheet in merge.items():
sheet.fillna('.', inplace=True)
ori_data[name] = sheet.to_dict('records')
return ori_data
def add_new_data(self, chipname, library_data, newer=True):
"""
增加新数据到已知芯片上
:param chipname:
:param library_data:
:param newer:
:return:
"""
self.index_assignments[chipname].extend(library_data['data'])
self.chip_barcode_recode[chipname].update({item['barcode'] for item in library_data['data']})
if newer:
self.chip_size[chipname] = library_data['size']
else:
self.chip_size[chipname] += library_data['size']
if library_data['lib_type'] in self.chip_lib_type[chipname]:
self.chip_lib_type[chipname][library_data['lib_type']] += library_data['size']
else:
self.chip_lib_type[chipname][library_data['lib_type']] = library_data['size']
def dec_barcode_radio(self, chipname):
data = self.index_assignments[chipname]
df = pd.DataFrame(data)
barcode_df = pd.DataFrame(df['barcode'].str.split('', expand=True).iloc[:, 1:-1].values,
columns=['T' + str(x) for x in range(16)]).join(df['data_needed'])
total = barcode_df['data_needed'].sum()
is_not_balance_list = []
for i in range(16):
column = 'T' + str(i)
col_df = barcode_df.groupby(column).agg({'data_needed': 'sum'})
# 去掉N计数
if 'N' in col_df.index:
base_N_size = col_df.loc['N', 'data_needed']
col_df = col_df.drop('N')
else:
base_N_size = 0
col_df['ratio'] = (col_df['data_needed']) / (total - base_N_size)
need_base_list = list()
ratio = col_df['ratio'].to_dict()
for decbase in ['A', 'T', 'C']:
if decbase not in ratio:
ratio[decbase] = 0
need_base_list.append(decbase)
continue
if ratio[decbase] < 0.1:
need_base_list.append(decbase)
# 小于标准的base 是不是空的,空的说明都满足
if len(need_base_list) > 2:
is_not_balance_list.append(
'[%s] 第%s位置, %s 有碱基不平衡,算出结果为 %s' % (chipname, i, need_base_list, ratio)
)
# 对于G不能超过10%
if 'G' not in ratio:
ratio['G'] = 0
if ratio['G'] > 0.7:
is_not_balance_list.append(
'[%s] 第%s位置, G 含量超过70%%,算出结果为 %s' % (chipname, i, ratio['G'])
)
if is_not_balance_list:
self.return_log.extend(is_not_balance_list)
print('有碱基不平衡性!\n', '\n'.join(is_not_balance_list))
@staticmethod
def read_rule():
df = pd.read_excel(os.path.join(basedir, 'rule', 'lib_type_limit.xlsx'))
return df.to_dict('index')
@staticmethod
def level(row):
if row['customer'] == '百奥益康' and '3\'' in row['lib_type']:
return 1
elif row['customer'] == '百奥益康' and '5\'' in row['lib_type']:
return 2
else:
return 100
def judge_data(self, chipname, library_data):
size = library_data['size']
library = library_data['library']
# 芯片大小不能超过设定限制
sizelimit = True
if self.chip_size[chipname] + size > self.data_limit:
sizelimit = False
self.logger.error(f'{library} {chipname} 文库相加大于设定限制')
# barcode有重复
notrepeatbarcode = True
if self.chip_barcode_recode[chipname].intersection({item['barcode'] for item in library_data['data']}):
notrepeatbarcode = False
self.logger.error(f'{library} {chipname} 文库有barcode重复')
# 特定文库不能超过限制
sp_lib1 = True
for _, myrule in self.read_rule().items():
lib_type = myrule['lib_type']
limit = myrule['limit']
if lib_type in self.chip_lib_type[chipname]:
if self.chip_lib_type[chipname][lib_type] + size > self.data_limit * limit:
sp_lib1 = False
self.logger.error(f'{library} {chipname} 文库有大于设定限制')
break
if sizelimit and notrepeatbarcode and sp_lib1:
return True
return False
def assign_samples(self):
ori_library_data = list()
ori_library_df = pd.DataFrame(self.ori_data['未测'])
ori_library_df['level'] = ori_library_df.apply(self.level, axis=1)
for library, library_df in ori_library_df.groupby('#library'):
ori_library_data.append(dict(
library=library,
size=library_df['data_needed'].sum(),
time=library_df['time'].values[0],
customer=library_df['customer'].values[0],
level=library_df['level'].values[0],
status=library_df['status'].values[0],
lib_type=library_df['lib_type'].values[0],
data=library_df.to_dict('records')
))
ori_sort_data = sorted(ori_library_data, key=lambda x: (x['level'], x['customer'], -x['size'], x['time']))
while ori_sort_data:
library_data = ori_sort_data[0]
chipname = f'lane{self.loc_chip_num}'
# 空白芯片直接添加
if chipname not in self.index_assignments:
self.add_new_data(chipname, library_data)
ori_sort_data.remove(library_data)
continue
# 判断条件
if self.judge_data(chipname, library_data):
self.add_new_data(chipname, library_data, newer=False)
ori_sort_data.remove(library_data)
else:
for j in range(len(ori_sort_data)):
newlibrary_data = ori_sort_data[j]
if self.judge_data(chipname, newlibrary_data):
ori_sort_data.remove(newlibrary_data)
self.add_new_data(chipname, newlibrary_data, newer=False)
break
j += 1
else:
# 代表接下来的数据放到这个chip当中都不行只有换chip了
self.loc_chip_num += 1
# 加完之后下面的数据可能加上去就慢了就换chip
if self.chip_size[chipname] > self.data_limit * 0.99:
self.loc_chip_num += 1
def run(self):
try:
self.assign_samples()
except Exception as e:
self.return_log.append(f'排样出错, 请联系!{e}')
self.index_assignments = {}
outputname = 'assignments_%s_%s' % (datetime.now().strftime("%m%d%H%M"), os.path.basename(self.path))
outputpath = os.path.join(self.output, 'result', outputname)
writer = pd.ExcelWriter(outputpath)
no_assign_data = list()
no_assign_chip = list()
for chip_idx, chip_assignments in self.index_assignments.items():
self.dec_barcode_radio(chip_idx)
df = pd.DataFrame(chip_assignments)
if df['data_needed'].sum() < self.data_limit * 0.8:
no_assign_chip.append(chip_idx)
no_assign_data.extend(chip_assignments)
continue
df.to_excel(writer, sheet_name=chip_idx, index=False)
pd.DataFrame(no_assign_data).to_excel(writer, sheet_name='未测', index=False)
if self.return_log:
log_res = [splog for splog in self.return_log if
not any(f'[{chip}]' in str(splog) for chip in no_assign_chip)]
pd.DataFrame(log_res).to_excel(writer, sheet_name='log', index=False)
writer.close()
return outputpath
if __name__ == '__main__':
start_time = time.time()
excel_file = 'example/0704_nova_1.xlsx'
output_file = ''
layout = AutoLayout(excel_file, output_file, data_limit=800)
layout.run()
end_time = time.time()
execution_time = end_time - start_time
print(f"代码执行时间为:{execution_time}")

View File

@ -1,32 +1,10 @@
import os
import socket
import pandas as pd import pandas as pd
from collections import defaultdict from collections import defaultdict
from datetime import datetime from datetime import datetime
import time import time
import logging
import os import os
from tools.client import recvdata, senddata from .common import basedir, log
basedir = os.path.dirname(os.path.realpath(__file__))
def log(name):
"""
日志
:param name:
:return: 返回logger对象
"""
logger = logging.getLogger('main')
logpath = os.path.join(basedir, 'log', name + '.log.txt')
logfile = logging.FileHandler(logpath, mode='w')
logfomat = logging.Formatter('%(message)s\t%(asctime)s')
logfile.setFormatter(logfomat)
logfile.setLevel(logging.DEBUG)
logger.addHandler(logfile)
return logger
class AutoLayout: class AutoLayout:
@ -160,7 +138,7 @@ class AutoLayout:
'%s%s位置, %s 有碱基不平衡,算出结果为 %s' % (chipname, i, need_base_list, ratio) '%s%s位置, %s 有碱基不平衡,算出结果为 %s' % (chipname, i, need_base_list, ratio)
) )
if len(is_not_balance_list) >2 : if len(is_not_balance_list) > 2:
self.return_log.append('有碱基不平衡性!') self.return_log.append('有碱基不平衡性!')
self.return_log.extend(is_not_balance_list) self.return_log.extend(is_not_balance_list)
print('有碱基不平衡性!\n', '\n'.join(is_not_balance_list)) print('有碱基不平衡性!\n', '\n'.join(is_not_balance_list))
@ -285,11 +263,14 @@ class AutoLayout:
pass pass
def run(self): def run(self):
try:
self.assign_samples() self.assign_samples()
except Exception as e:
self.return_log.append(f'排样出错, 请联系!{e}')
self.index_assignments = {}
outputname = 'assignments_%s_%s' % (datetime.now().strftime("%m%d%H%M"), os.path.basename(self.path)) outputname = 'assignments_%s_%s' % (datetime.now().strftime("%m%d%H%M"), os.path.basename(self.path))
outputpath = os.path.join(self.output, 'result', outputname) outputpath = os.path.join(self.output, 'result', outputname)
writer = pd.ExcelWriter(outputpath) writer = pd.ExcelWriter(outputpath)
no_assign_data = list() no_assign_data = list()
for chip_idx, chip_assignments in self.index_assignments.items(): for chip_idx, chip_assignments in self.index_assignments.items():
self.dec_barcode_radio(chip_idx) self.dec_barcode_radio(chip_idx)
@ -309,32 +290,14 @@ class AutoLayout:
return outputpath return outputpath
def server():
myserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
adrss = ("", 8190)
myserver.bind(adrss)
myserver.listen(5)
while True:
try:
myclient, adddr = myserver.accept()
recv_content = recvdata(myclient, os.path.join(basedir, 'example'))
print('接收到了文件')
layout = AutoLayout(recv_content)
outputpath = layout.run()
senddata(myclient, outputpath)
except Exception as e:
print(e)
continue
if __name__ == '__main__': if __name__ == '__main__':
# start_time = time.time() start_time = time.time()
# excel_file = 'example/06211429_包lane广西.xlsx' excel_file = 'example/07031754_20230703.xlsx'
# output_file = '' output_file = ''
# layout = AutoLayout(excel_file, output_file) layout = AutoLayout(excel_file, output_file)
# layout.run() layout.run()
# end_time = time.time() end_time = time.time()
# execution_time = end_time - start_time execution_time = end_time - start_time
# print(f"代码执行时间为:{execution_time} 秒") print(f"代码执行时间为:{execution_time}")
server() # server()