Page 1 of 1
Position performance in a pgn database
Posted: Fri Jul 12, 2019 11:27 am
by giovanni
Is there a command line tool that takes as input a epd or a FEN string and reports its performance in a pgn database? For performance, the white score percentage would suffice, but if it would calculates also the Elo performance would be even better.
I know that several GUIs like Scid, ChessBase, etc., already do this, but I am looking for a command line tool.
Thanks in advance.
Re: Position performance in a pgn database
Posted: Sun Jul 14, 2019 11:45 am
by Ferdy
giovanni wrote: ↑Fri Jul 12, 2019 11:27 am
Is there a command line
tool that takes as input a epd or a FEN string and reports its performance in a pgn database? For performance, the white score percentage would suffice, but if it would calculates also the Elo performance would be even better.
I know that several GUIs like Scid, ChessBase, etc., already do this, but I am looking for a command line
tool.
Thanks in advance.
This one
https://github.com/mcostalba/scoutfish is capable of doing what you need.
A sample python code is available see at end of page. scoutfish.py module is inside the src folder, you need it. Also pip install pexpect.
Try this script, change the pgn filename.
Code: Select all
#!/usr/bin/env python3
"""
sc.py
"""
import time
from scoutfish import Scoutfish
def search(eng, pgn, threads=1, fen=None, res=None):
p = Scoutfish(eng)
p.setoption('threads', threads) # Will use 4 threads for searching
p.open(pgn)
q = { "sub-fen": fen, "result": res }
result = p.scout(q)
num = result['match count']
p.close()
return num
def main():
pgn = 'clean_KingBase2019-A00-A39.pgn'
eng = 'scoutfish.exe'
threads = 1
fen = input('enter fen? ')
t1 = time.perf_counter()
res = '1-0'
wwins = search(eng, pgn, threads, fen, res)
res = '0-1'
wloss = search(eng, pgn, threads, fen, res)
res = '1/2-1/2'
wdraw = search(eng, pgn, threads, fen, res)
total = wwins + wloss + wdraw
score = wwins + wdraw/2
rate = score/total
print('rate: {:0.2f}% wpov'.format(rate*100))
print('elapsed sec: {:0.2f}'.format(time.perf_counter() - t1))
if __name__ == "__main__":
main()
Sample run.
enter fen? rnbqkb1r/pppp1ppp/5n2/4p3/2P5/6P1/PP1PPP1P/RNBQKBNR w KQkq - 1 3
rate: 53.95% wpov
elapsed sec: 2.13
source pgn is around 250k games.
Download scoutfish.exe at
https://github.com/pychess/scoutfish/releases
Place scoutfish.exe, scoutfish.py and sc.py in same folder.
Install pexpect with,
pip install pexpect
Re: Position performance in a pgn database
Posted: Sun Jul 14, 2019 3:04 pm
by giovanni
Ferdy wrote: ↑Sun Jul 14, 2019 11:45 am
giovanni wrote: ↑Fri Jul 12, 2019 11:27 am
Is there a command line
tool that takes as input a epd or a FEN string and reports its performance in a pgn database? For performance, the white score percentage would suffice, but if it would calculates also the Elo performance would be even better.
I know that several GUIs like Scid, ChessBase, etc., already do this, but I am looking for a command line
tool.
Thanks in advance.
This one
https://github.com/mcostalba/scoutfish is capable of doing what you need.
A sample python code is available see at end of page. scoutfish.py module is inside the src folder, you need it. Also pip install pexpect.
Try this script, change the pgn filename.
Code: Select all
#!/usr/bin/env python3
"""
sc.py
"""
import time
from scoutfish import Scoutfish
def search(eng, pgn, threads=1, fen=None, res=None):
p = Scoutfish(eng)
p.setoption('threads', threads) # Will use 4 threads for searching
p.open(pgn)
q = { "sub-fen": fen, "result": res }
result = p.scout(q)
num = result['match count']
p.close()
return num
def main():
pgn = 'clean_KingBase2019-A00-A39.pgn'
eng = 'scoutfish.exe'
threads = 1
fen = input('enter fen? ')
t1 = time.perf_counter()
res = '1-0'
wwins = search(eng, pgn, threads, fen, res)
res = '0-1'
wloss = search(eng, pgn, threads, fen, res)
res = '1/2-1/2'
wdraw = search(eng, pgn, threads, fen, res)
total = wwins + wloss + wdraw
score = wwins + wdraw/2
rate = score/total
print('rate: {:0.2f}% wpov'.format(rate*100))
print('elapsed sec: {:0.2f}'.format(time.perf_counter() - t1))
if __name__ == "__main__":
main()
Sample run.
enter fen? rnbqkb1r/pppp1ppp/5n2/4p3/2P5/6P1/PP1PPP1P/RNBQKBNR w KQkq - 1 3
rate: 53.95% wpov
elapsed sec: 2.13
source pgn is around 250k games.
Download scoutfish.exe at
https://github.com/pychess/scoutfish/releases
Place scoutfish.exe, scoutfish.py and sc.py in same folder.
Install pexpect with,
pip install pexpect
Thanks Ferdy. Appreciated. Thanks also for drawing our attention to this very interesting
tool.
Re: Position performance in a pgn database
Posted: Sun Jul 14, 2019 8:52 pm
by Ferdy
giovanni wrote: ↑Fri Jul 12, 2019 11:27 am
Is there a command line
tool that takes as input a epd or a FEN string and reports its performance in a pgn database? For performance, the white score percentage would suffice, but if it would calculates also the Elo performance would be even better.
The module scoutfish.py can extract game headers, with that headers we can calculate the position's rating perf.
Using rating perf simple formula
Code: Select all
white elo perf = (sum_elo_black + 400 * (white_wins - white_loses)) / num_games
from
https://en.wikipedia.org/wiki/Elo_ratin ... nce_rating
Make sure your games have ratings.
Sample run.
Code: Select all
enter pgn? clean_KingBase2019-A00-A39.pgn
enter fen? rnbqkb1r/pppp1ppp/5n2/4p3/2P5/6P1/PP1PPP1P/RNBQKBNR w KQkq - 1 3
pgn: clean_KingBase2019-A00-A39.pgn
FEN: rnbqkb1r/pppp1ppp/5n2/4p3/2P5/6P1/PP1PPP1P/RNBQKBNR w KQkq - 1 3
white score rate : 53.95%
white average_rating : 2368
white Elo perf : 2399
elapsed sec: 3.58
Revised script.
Code: Select all
#!/usr/bin/env python3
"""
sc.py
"""
import time
from scoutfish import Scoutfish
def search(eng, pgn, threads=1, fen=None, res=None):
p = Scoutfish(eng)
p.setoption('threads', threads)
p.open(pgn)
res_stat = []
white_rating = []
black_rating = []
white_wins = 0
white_loses = 0
for r in res:
q = { "sub-fen": fen, "result": r }
result = p.scout(q)
num = result['match count']
res_stat.append(num)
# Get game headers
games = p.get_games(result['matches'])
headers = p.get_game_headers(games)
for h in headers:
wr = int(h['WhiteElo'])
br = int(h['BlackElo'])
r = h['Result']
if r == '1-0':
white_wins += 1
elif r == '0-1':
white_loses += 1
white_rating.append(wr)
black_rating.append(br)
p.close()
white_average_rating = sum(white_rating)/len(white_rating)
num_games = len(black_rating)
white_elo_perf = sum(black_rating) + 400 * (white_wins - white_loses)
white_elo_perf = white_elo_perf/num_games
return res_stat[0], res_stat[1], res_stat[2], white_average_rating, white_elo_perf
def main():
eng = 'scoutfish.exe'
threads = 1
res = ['1-0', '0-1', '1/2-1/2']
# pgn= 'clean_KingBase2019-A00-A39.pgn'
# fen = 'rnbqkb1r/pppp1ppp/5n2/4p3/2P5/6P1/PP1PPP1P/RNBQKBNR w KQkq - 1 3'
pgn = input('enter pgn? ')
fen = input('enter fen? ')
t1 = time.perf_counter()
wwins, wloss, wdraw, white_average_rating, white_elo_perf = \
search(eng, pgn, threads, fen, res)
total = wwins + wloss + wdraw
score = wwins + wdraw/2
score_rate = 100*score/total
print()
print('pgn: {}'.format(pgn))
print('FEN: {}'.format(fen))
print('white score rate : {:0.2f}%'.format(score_rate))
print('white average_rating : {:0.0f}'.format(white_average_rating))
print('white Elo perf : {:0.0f}'.format(white_elo_perf))
print('\nelapsed sec: {:0.2f}'.format(time.perf_counter() - t1))
if __name__ == "__main__":
main()
Re: Position performance in a pgn database
Posted: Mon Jul 15, 2019 9:46 am
by giovanni
Nice. Thanks again, Ferdy.