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.