FAM file parser
A library for parsing FAM files from Python or Javascript.
Python library
Installation:
pip install fam-parser
Use as a library:
import sys
from fam_parser import FamParser
parser = FamParser()
parser.read(open(example.fam'))
parser.write(sys.stdout)
Command line invocation:
fam_parser example.fam -
You can also invoke it directly from the repository root directory without
installation:
python -m python.fam_parser example.fam -
Javascript library
Installation:
npm install fam-parser
Installation from source:
npm install
npm run dist
Use as a library:
var FamParser = require('fam-parser');
var parser = new FamParser(fs.readFileSync(
'example.fam').toString('binary')
);
parser.getMembers().forEach(function(member) {
console.log(member.SURNAME);
});
Command line invocation:
./node_modules/.bin/fam-parser example.fam
(Or, if you installed globally using npm install -g, the fam-parser binary
should be in your $PATH.)
You can also invoke it directly from the repository root directory without
installation:
node javascript/cli.js example.fam
Development of the FAM parser
We use the Python implementation for most of the development as it includes
more debugging functionality. Any changes are later lifted to the Javascript
implementation.
Preparations
First, make sure that wine is installed and that your CPU allows execution of
16-bit instructions:
echo 1 > /proc/sys/abi/ldt16
Reverse engineering
Run Cyrillic:
wine cyrillic.exe
And start editing a pedigree. Use xxd and watch to find differences:
while true; do watch --differences=permanent xxd pedigree.fam; done
Press Ctrl+c to clear the highlights.
Debugging
If something is wrong, then probably a skipped field is now assumed to be of
fixed size, while it should be of variable size. To find the offending field,
add the following line to the function _set_field:
print name
The offending field is probably one of the unnamed fields above the one you
found, hopefully the nearest one.
Now you can give the unnamed field a name so you can inspect its content.
while true; do
watch --differences=permanent \
"fam_parser -d pedigree.fam - | tail -100 | head -50"
done
Vary the values for head and tail to focus on the part of the output you
want to inspect.