合并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
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):
"""
@ -18,15 +23,16 @@ def recvdata(conn, path):
header_dic = json.loads(header_json)
content_len = header_dic['contentlen']
content_name = header_dic['contentname']
select_type = header_dic['select_type']
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')
while recv_len < content_len:
correntrecv = conn.recv(1024 * 1000)
file.write(correntrecv)
recv_len += len(correntrecv)
file.close()
return fielpath
return fielpath, select_type
def senddata(conn, path, message=None):
@ -57,4 +63,27 @@ def senddata(conn, path, message=None):
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
from collections import defaultdict
from datetime import datetime
import time
import logging
import os
from tools.client import recvdata, senddata
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
from .common import basedir, log
class AutoLayout:
@ -160,7 +138,7 @@ class AutoLayout:
'%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.extend(is_not_balance_list)
print('有碱基不平衡性!\n', '\n'.join(is_not_balance_list))
@ -285,11 +263,14 @@ class AutoLayout:
pass
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()
for chip_idx, chip_assignments in self.index_assignments.items():
self.dec_barcode_radio(chip_idx)
@ -309,32 +290,14 @@ class AutoLayout:
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__':
# start_time = time.time()
# excel_file = 'example/06211429_包lane广西.xlsx'
# output_file = ''
# layout = AutoLayout(excel_file, output_file)
# layout.run()
# end_time = time.time()
# execution_time = end_time - start_time
# print(f"代码执行时间为:{execution_time} 秒")
start_time = time.time()
excel_file = 'example/07031754_20230703.xlsx'
output_file = ''
layout = AutoLayout(excel_file, output_file)
layout.run()
end_time = time.time()
execution_time = end_time - start_time
print(f"代码执行时间为:{execution_time}")
server()
# server()