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.
Position performance in a pgn database
Moderator: Ras
-
- Posts: 4845
- Joined: Sun Aug 10, 2008 3:15 pm
- Location: Philippines
Re: Position performance in a pgn database
This one https://github.com/mcostalba/scoutfish is capable of doing what you need.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.
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()
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
-
- Posts: 142
- Joined: Wed Jul 08, 2015 12:30 pm
Re: Position performance in a pgn database
Thanks Ferdy. Appreciated. Thanks also for drawing our attention to this very interesting tool.Ferdy wrote: ↑Sun Jul 14, 2019 11:45 amThis one https://github.com/mcostalba/scoutfish is capable of doing what you need.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.
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
-
- Posts: 4845
- Joined: Sun Aug 10, 2008 3:15 pm
- Location: Philippines
Re: Position performance in a pgn database
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
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()
-
- Posts: 142
- Joined: Wed Jul 08, 2015 12:30 pm
Re: Position performance in a pgn database
Nice. Thanks again, Ferdy.