add SymmetryChecker
diff --git a/genomix/genomix-hadoop/data/webmap/PathMerge_TestSet/sameWithEdge/okay b/genomix/genomix-hadoop/data/webmap/PathMerge_TestSet/sameWithEdge/okay
new file mode 100644
index 0000000..7fb459e
--- /dev/null
+++ b/genomix/genomix-hadoop/data/webmap/PathMerge_TestSet/sameWithEdge/okay
@@ -0,0 +1 @@
+1 GTAAAAAAAAAACC
diff --git a/genomix/genomix-hadoop/src/test/java/edu/uci/ics/genomix/hadoop/contrailgraphbuilding/GraphBuildingTestSuite.java b/genomix/genomix-hadoop/src/test/java/edu/uci/ics/genomix/hadoop/contrailgraphbuilding/GraphBuildingTestSuite.java
index 63e875a..b2bafef 100644
--- a/genomix/genomix-hadoop/src/test/java/edu/uci/ics/genomix/hadoop/contrailgraphbuilding/GraphBuildingTestSuite.java
+++ b/genomix/genomix-hadoop/src/test/java/edu/uci/ics/genomix/hadoop/contrailgraphbuilding/GraphBuildingTestSuite.java
@@ -30,7 +30,7 @@
// + "P2_5", PreFix + File.separator
// + "P2_7", PreFix + File.separator
// + "P2_8"
- + "same"
+ + "sameWithEdge"
};
// + "SimpleRectangle", PreFix + File.separator
// + "MediumRectangle", PreFix + File.separator
diff --git a/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/..binmerge.crc b/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/..binmerge.crc
new file mode 100644
index 0000000..7936d21
--- /dev/null
+++ b/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/..binmerge.crc
Binary files differ
diff --git a/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/.binmerge b/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/.binmerge
new file mode 100755
index 0000000..ac38fae
--- /dev/null
+++ b/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/.binmerge
Binary files differ
diff --git a/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/bin/.part-00000.crc b/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/bin/.part-00000.crc
new file mode 100644
index 0000000..0bfaa03
--- /dev/null
+++ b/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/bin/.part-00000.crc
Binary files differ
diff --git a/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/bin/part-00000 b/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/bin/part-00000
new file mode 100755
index 0000000..abba88d
--- /dev/null
+++ b/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/bin/part-00000
Binary files differ
diff --git a/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/data b/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/data
new file mode 100644
index 0000000..bd2f057
--- /dev/null
+++ b/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/data
@@ -0,0 +1,5 @@
+AAA {[{AAA:[1]},{AAC:[1]}] [] [] [{AAA:[1]},{TAA:[1]}] {5':[], ~5':[]} 8.0x}
+TAA {[{AAA:[1]}] [] [] [{GTA:[1]}] {5':[], ~5':[]} 1.0x}
+GTA {[{TAA:[1]}] [] [] [] {5':[(1-0_0)], ~5':[]} 1.0x}
+AAC {[{ACC:[1]}] [] [] [{AAA:[1]}] {5':[], ~5':[]} 1.0x}
+ACC {[] [] [] [{AAC:[1]}] {5':[], ~5':[]} 1.0x}
diff --git a/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/graphviz/result.svg b/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/graphviz/result.svg
new file mode 100644
index 0000000..fe1ec66
--- /dev/null
+++ b/genomix/genomix-pregelix/data/TestSet/PathMerge/sameWithEdge/graphviz/result.svg
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by graphviz version 2.26.3 (20100126.1600)
+ -->
+<!-- Title: G Pages: 1 -->
+<svg width="356pt" height="249pt"
+ viewBox="0.00 0.00 356.44 249.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 245)">
+<title>G</title>
+<polygon fill="white" stroke="white" points="-4,5 -4,-245 353.441,-245 353.441,5 -4,5"/>
+<!-- AAA -->
+<g id="node1" class="node"><title>AAA</title>
+<polygon fill="none" stroke="black" points="12.4406,-61 12.4406,-165 68.4406,-165 68.4406,-61 12.4406,-61"/>
+<text text-anchor="middle" x="40.4406" y="-148.4" font-family="Times Roman,serif" font-size="14.00">AAA</text>
+<polyline fill="none" stroke="black" points="12.4406,-139 68.4406,-139 "/>
+<text text-anchor="middle" x="40.4406" y="-122.4" font-family="Times Roman,serif" font-size="14.00">5':[]</text>
+<polyline fill="none" stroke="black" points="12.4406,-113 68.4406,-113 "/>
+<text text-anchor="middle" x="40.4406" y="-96.4" font-family="Times Roman,serif" font-size="14.00">~5':[]</text>
+<polyline fill="none" stroke="black" points="12.4406,-87 68.4406,-87 "/>
+<text text-anchor="middle" x="40.4406" y="-70.4" font-family="Times Roman,serif" font-size="14.00">8.0</text>
+</g>
+<!-- AAA->AAA -->
+<g id="edge2" class="edge"><title>AAA->AAA</title>
+<path fill="none" stroke="black" d="M34.1489,-165.202C34.857,-175.592 36.9543,-183 40.4406,-183 42.6196,-183 44.2559,-180.106 45.3496,-175.399"/>
+<polygon fill="black" stroke="black" points="48.8568,-175.582 46.7323,-165.202 41.9203,-174.641 48.8568,-175.582"/>
+<text text-anchor="middle" x="40.4406" y="-188.4" font-family="Times Roman,serif" font-size="14.00">FF: [1]</text>
+</g>
+<!-- AAA->AAA -->
+<g id="edge8" class="edge"><title>AAA->AAA</title>
+<path fill="none" stroke="red" d="M12.1844,-136.431C-10.5504,-165.905 -1.13167,-201 40.4406,-201 78.1155,-201 89.383,-172.177 74.2431,-144.835"/>
+<polygon fill="red" stroke="red" points="77.1261,-142.85 68.6967,-136.431 71.2837,-146.705 77.1261,-142.85"/>
+<text text-anchor="middle" x="40.4406" y="-206.4" font-family="Times Roman,serif" font-size="14.00">RR: [1]</text>
+</g>
+<!-- AAC -->
+<g id="node4" class="node"><title>AAC</title>
+<polygon fill="none" stroke="black" points="152.441,-122 152.441,-226 208.441,-226 208.441,-122 152.441,-122"/>
+<text text-anchor="middle" x="180.441" y="-209.4" font-family="Times Roman,serif" font-size="14.00">AAC</text>
+<polyline fill="none" stroke="black" points="152.441,-200 208.441,-200 "/>
+<text text-anchor="middle" x="180.441" y="-183.4" font-family="Times Roman,serif" font-size="14.00">5':[]</text>
+<polyline fill="none" stroke="black" points="152.441,-174 208.441,-174 "/>
+<text text-anchor="middle" x="180.441" y="-157.4" font-family="Times Roman,serif" font-size="14.00">~5':[]</text>
+<polyline fill="none" stroke="black" points="152.441,-148 208.441,-148 "/>
+<text text-anchor="middle" x="180.441" y="-131.4" font-family="Times Roman,serif" font-size="14.00">1.0</text>
+</g>
+<!-- AAA->AAC -->
+<g id="edge4" class="edge"><title>AAA->AAC</title>
+<path fill="none" stroke="black" d="M68.5419,-141.19C74.1287,-145.666 80.2061,-149.851 86.4406,-153 103.658,-161.698 124.447,-166.821 142.091,-169.825"/>
+<polygon fill="black" stroke="black" points="141.65,-173.298 152.066,-171.36 142.714,-166.38 141.65,-173.298"/>
+<text text-anchor="middle" x="110.441" y="-173.4" font-family="Times Roman,serif" font-size="14.00">FF: [1]</text>
+</g>
+<!-- TAA -->
+<g id="node6" class="node"><title>TAA</title>
+<polygon fill="none" stroke="black" points="152.441,-0 152.441,-104 208.441,-104 208.441,-0 152.441,-0"/>
+<text text-anchor="middle" x="180.441" y="-87.4" font-family="Times Roman,serif" font-size="14.00">TAA</text>
+<polyline fill="none" stroke="black" points="152.441,-78 208.441,-78 "/>
+<text text-anchor="middle" x="180.441" y="-61.4" font-family="Times Roman,serif" font-size="14.00">5':[]</text>
+<polyline fill="none" stroke="black" points="152.441,-52 208.441,-52 "/>
+<text text-anchor="middle" x="180.441" y="-35.4" font-family="Times Roman,serif" font-size="14.00">~5':[]</text>
+<polyline fill="none" stroke="black" points="152.441,-26 208.441,-26 "/>
+<text text-anchor="middle" x="180.441" y="-9.4" font-family="Times Roman,serif" font-size="14.00">1.0</text>
+</g>
+<!-- AAA->TAA -->
+<g id="edge6" class="edge"><title>AAA->TAA</title>
+<path fill="none" stroke="red" d="M68.7717,-100.656C90.1198,-91.3541 119.597,-78.5102 142.906,-68.3543"/>
+<polygon fill="red" stroke="red" points="144.382,-71.5291 152.152,-64.3259 141.586,-65.1118 144.382,-71.5291"/>
+<text text-anchor="middle" x="110.441" y="-96.4" font-family="Times Roman,serif" font-size="14.00">RR: [1]</text>
+</g>
+<!-- AAC->AAA -->
+<g id="edge18" class="edge"><title>AAC->AAA</title>
+<path fill="none" stroke="red" d="M152.409,-143.288C146.857,-138.578 140.774,-134.221 134.441,-131 117.231,-122.248 96.2786,-117.733 78.5263,-115.411"/>
+<polygon fill="red" stroke="red" points="78.8251,-111.923 68.4964,-114.282 78.0421,-118.879 78.8251,-111.923"/>
+<text text-anchor="middle" x="110.441" y="-136.4" font-family="Times Roman,serif" font-size="14.00">RR: [1]</text>
+</g>
+<!-- ACC -->
+<g id="node13" class="node"><title>ACC</title>
+<polygon fill="none" stroke="black" points="292.441,-137 292.441,-241 348.441,-241 348.441,-137 292.441,-137"/>
+<text text-anchor="middle" x="320.441" y="-224.4" font-family="Times Roman,serif" font-size="14.00">ACC</text>
+<polyline fill="none" stroke="black" points="292.441,-215 348.441,-215 "/>
+<text text-anchor="middle" x="320.441" y="-198.4" font-family="Times Roman,serif" font-size="14.00">5':[]</text>
+<polyline fill="none" stroke="black" points="292.441,-189 348.441,-189 "/>
+<text text-anchor="middle" x="320.441" y="-172.4" font-family="Times Roman,serif" font-size="14.00">~5':[]</text>
+<polyline fill="none" stroke="black" points="292.441,-163 348.441,-163 "/>
+<text text-anchor="middle" x="320.441" y="-146.4" font-family="Times Roman,serif" font-size="14.00">1.0</text>
+</g>
+<!-- AAC->ACC -->
+<g id="edge16" class="edge"><title>AAC->ACC</title>
+<path fill="none" stroke="black" d="M208.772,-177.035C229.835,-179.292 258.813,-182.397 281.97,-184.878"/>
+<polygon fill="black" stroke="black" points="281.836,-188.384 292.152,-185.969 282.581,-181.424 281.836,-188.384"/>
+<text text-anchor="middle" x="250.441" y="-188.4" font-family="Times Roman,serif" font-size="14.00">FF: [1]</text>
+</g>
+<!-- TAA->AAA -->
+<g id="edge10" class="edge"><title>TAA->AAA</title>
+<path fill="none" stroke="black" d="M152.182,-45.1741C132.676,-41.9735 106.705,-40.8023 86.4406,-51 82.7741,-52.8452 79.3264,-55.1361 76.0979,-57.7399"/>
+<polygon fill="black" stroke="black" points="73.4652,-55.4085 68.5237,-64.7804 78.231,-60.5356 73.4652,-55.4085"/>
+<text text-anchor="middle" x="110.441" y="-56.4" font-family="Times Roman,serif" font-size="14.00">FF: [1]</text>
+</g>
+<!-- GTA -->
+<g id="node10" class="node"><title>GTA</title>
+<polygon fill="grey" stroke="black" points="292.441,-10 292.441,-114 348.441,-114 348.441,-10 292.441,-10"/>
+<text text-anchor="middle" x="320.441" y="-97.4" font-family="Times Roman,serif" font-size="14.00">GTA</text>
+<polyline fill="none" stroke="black" points="292.441,-88 348.441,-88 "/>
+<text text-anchor="middle" x="320.441" y="-71.4" font-family="Times Roman,serif" font-size="14.00">5':[1]</text>
+<polyline fill="none" stroke="black" points="292.441,-62 348.441,-62 "/>
+<text text-anchor="middle" x="320.441" y="-45.4" font-family="Times Roman,serif" font-size="14.00">~5':[]</text>
+<polyline fill="none" stroke="black" points="292.441,-36 348.441,-36 "/>
+<text text-anchor="middle" x="320.441" y="-19.4" font-family="Times Roman,serif" font-size="14.00">1.0</text>
+</g>
+<!-- TAA->GTA -->
+<g id="edge12" class="edge"><title>TAA->GTA</title>
+<path fill="none" stroke="red" d="M208.608,-65.6511C214.38,-67.8691 220.508,-69.823 226.441,-71 244.551,-74.5931 264.92,-73.2827 282.055,-70.688"/>
+<polygon fill="red" stroke="red" points="282.993,-74.0784 292.257,-68.9387 281.809,-67.1791 282.993,-74.0784"/>
+<text text-anchor="middle" x="250.441" y="-78.4" font-family="Times Roman,serif" font-size="14.00">RR: [1]</text>
+</g>
+<!-- GTA->TAA -->
+<g id="edge14" class="edge"><title>GTA->TAA</title>
+<path fill="none" stroke="black" d="M291.991,-52.6474C286.242,-51.1308 280.195,-49.7975 274.441,-49 256.226,-46.4756 235.844,-46.753 218.728,-47.8556"/>
+<polygon fill="black" stroke="black" points="218.247,-44.382 208.541,-48.631 218.778,-51.3618 218.247,-44.382"/>
+<text text-anchor="middle" x="250.441" y="-54.4" font-family="Times Roman,serif" font-size="14.00">FF: [1]</text>
+</g>
+<!-- ACC->AAC -->
+<g id="edge20" class="edge"><title>ACC->AAC</title>
+<path fill="none" stroke="red" d="M292.414,-165.618C286.775,-162.072 280.66,-158.95 274.441,-157 256.45,-151.358 235.9,-154.08 218.612,-158.85"/>
+<polygon fill="red" stroke="red" points="217.385,-155.565 208.854,-161.847 219.441,-162.256 217.385,-155.565"/>
+<text text-anchor="middle" x="250.441" y="-162.4" font-family="Times Roman,serif" font-size="14.00">RR: [1]</text>
+</g>
+</g>
+</svg>
diff --git a/genomix/genomix-pregelix/data/TestSet/SymmetryChecker/2/bin/part-00000 b/genomix/genomix-pregelix/data/TestSet/SymmetryChecker/2/bin/part-00000
new file mode 100755
index 0000000..d3766af
--- /dev/null
+++ b/genomix/genomix-pregelix/data/TestSet/SymmetryChecker/2/bin/part-00000
Binary files differ
diff --git a/genomix/genomix-pregelix/data/TestSet/SymmetryChecker/2/graphviz/result.ps b/genomix/genomix-pregelix/data/TestSet/SymmetryChecker/2/graphviz/result.ps
new file mode 100644
index 0000000..3afc04f
--- /dev/null
+++ b/genomix/genomix-pregelix/data/TestSet/SymmetryChecker/2/graphviz/result.ps
@@ -0,0 +1,329 @@
+%!PS-Adobe-3.0
+%%Creator: graphviz version 2.26.3 (20100126.1600)
+%%Title: G
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+ dup dup findfont dup length dict begin
+ { 1 index /FID ne { def }{ pop pop } ifelse
+ } forall
+ /Encoding EncodingVector def
+ currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+ dup 1 exch div /InvScaleFactor exch def
+ scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage { % i j npages
+ /npages exch def
+ /j exch def
+ /i exch def
+ /str 10 string def
+ npages 1 gt {
+ gsave
+ coordfont setfont
+ 0 0 moveto
+ (\() show i str cvs show (,) show j str cvs show (\)) show
+ grestore
+ } if
+} bind def
+
+/set_font {
+ findfont exch
+ scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext { % width text
+ /text exch def
+ /width exch def
+ gsave
+ width 0 gt {
+ [] 0 setdash
+ text stringwidth pop width exch sub text length div 0 text ashow
+ } if
+ grestore
+} def
+
+/boxprim { % xcorner ycorner xsize ysize
+ 4 2 roll
+ moveto
+ 2 copy
+ exch 0 rlineto
+ 0 exch rlineto
+ pop neg 0 rlineto
+ closepath
+} bind def
+
+/ellipse_path {
+ /ry exch def
+ /rx exch def
+ /y exch def
+ /x exch def
+ matrix currentmatrix
+ newpath
+ x y translate
+ rx ry scale
+ 0 0 1 0 360 arc
+ setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+ [ % layer color sequence - darkest to lightest
+ [0 0 0]
+ [.2 .8 .8]
+ [.4 .8 .8]
+ [.6 .8 .8]
+ [.8 .8 .8]
+ ]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+ layercolorseq curlayer 1 sub layerlen mod get
+ aload pop sethsbcolor
+ /nodecolor {nopcolor} def
+ /edgecolor {nopcolor} def
+ /graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+ /myupper exch def
+ /mylower exch def
+ curlayer mylower lt
+ curlayer myupper gt
+ or
+ {invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+ userdict (<<) cvn ([) cvn load put
+ userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 240 148
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 204 112 boxprim clip newpath
+1 1 set_scale 0 rotate 40 41 translate
+% ATA
+gsave
+1 setlinewidth
+0 0 0 nodecolor
+newpath 0 0 moveto
+0 104 lineto
+56 104 lineto
+56 0 lineto
+closepath stroke
+0 0 0 nodecolor
+14 /Times-Roman set_font
+14 87.4 moveto 28 (ATA) alignedtext
+1 setlinewidth
+0 0 0 nodecolor
+newpath 0 78 moveto
+56 78 lineto
+stroke
+0 0 0 nodecolor
+14 /Times-Roman set_font
+14 61.4 moveto 28 (5':[]) alignedtext
+1 setlinewidth
+0 0 0 nodecolor
+newpath 0 52 moveto
+56 52 lineto
+stroke
+0 0 0 nodecolor
+14 /Times-Roman set_font
+8 35.4 moveto 40 (~5':[]) alignedtext
+1 setlinewidth
+0 0 0 nodecolor
+newpath 0 26 moveto
+56 26 lineto
+stroke
+0 0 0 nodecolor
+14 /Times-Roman set_font
+16.5 9.4 moveto 23 (1.0) alignedtext
+grestore
+% AAT
+gsave
+0 0 0.75294 nodecolor
+newpath 140 0 moveto
+140 104 lineto
+196 104 lineto
+196 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0 0 0 nodecolor
+newpath 140 0 moveto
+140 104 lineto
+196 104 lineto
+196 0 lineto
+closepath stroke
+0 0 0 nodecolor
+14 /Times-Roman set_font
+153.5 87.4 moveto 29 (AAT) alignedtext
+1 setlinewidth
+filled
+0 0 0 nodecolor
+newpath 140 78 moveto
+196 78 lineto
+stroke
+0 0 0 nodecolor
+14 /Times-Roman set_font
+149.5 61.4 moveto 37 (5':[1]) alignedtext
+1 setlinewidth
+filled
+0 0 0 nodecolor
+newpath 140 52 moveto
+196 52 lineto
+stroke
+0 0 0 nodecolor
+14 /Times-Roman set_font
+148 35.4 moveto 40 (~5':[]) alignedtext
+1 setlinewidth
+filled
+0 0 0 nodecolor
+newpath 140 26 moveto
+196 26 lineto
+stroke
+0 0 0 nodecolor
+14 /Times-Roman set_font
+156.5 9.4 moveto 23 (1.0) alignedtext
+grestore
+% ATA->AAT
+gsave
+1 setlinewidth
+0 1 1 edgecolor
+newpath 56.33 52 moveto
+77.39 52 106.37 52 129.53 52 curveto
+stroke
+0 1 1 edgecolor
+newpath 129.71 55.5 moveto
+139.71 52 lineto
+129.71 48.5 lineto
+closepath fill
+1 setlinewidth
+solid
+0 1 1 edgecolor
+newpath 129.71 55.5 moveto
+139.71 52 lineto
+129.71 48.5 lineto
+closepath stroke
+0 0 0 edgecolor
+14 /Times-Roman set_font
+74 57.4 moveto 48 (RR: [1]) alignedtext
+grestore
+% AAT->ATA
+gsave
+1 setlinewidth
+0 0 0 edgecolor
+newpath 139.51 35.99 moveto
+133.87 33.51 127.87 31.33 122 30 curveto
+101.2 25.28 94.8 25.28 74 30 curveto
+71.34 30.6 68.65 31.38 65.99 32.28 curveto
+stroke
+0 0 0 edgecolor
+newpath 64.53 29.09 moveto
+56.49 35.99 lineto
+67.08 35.61 lineto
+closepath fill
+1 setlinewidth
+solid
+0 0 0 edgecolor
+newpath 64.53 29.09 moveto
+56.49 35.99 lineto
+67.08 35.61 lineto
+closepath stroke
+0 0 0 edgecolor
+14 /Times-Roman set_font
+75.5 35.4 moveto 45 (FF: [1]) alignedtext
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 240 148
+end
+restore
+%%EOF
diff --git a/genomix/genomix-pregelix/data/TestSet/SymmetryChecker/2/test.txt b/genomix/genomix-pregelix/data/TestSet/SymmetryChecker/2/test.txt
new file mode 100644
index 0000000..51e1252
--- /dev/null
+++ b/genomix/genomix-pregelix/data/TestSet/SymmetryChecker/2/test.txt
@@ -0,0 +1,2 @@
+ATA {[] [] [] [{AAT:[1]}] {5':[], ~5':[]} 1.0x}
+AAT {[{ATA:[1]}] [] [] [] {5':[(1-0_0)], ~5':[]} 1.0x}
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/checker/SymmetryCheckerVertex.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/checker/SymmetryCheckerVertex.java
new file mode 100644
index 0000000..1d86859
--- /dev/null
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/checker/SymmetryCheckerVertex.java
@@ -0,0 +1,57 @@
+package edu.uci.ics.genomix.pregelix.checker;
+
+import java.util.Iterator;
+
+import edu.uci.ics.genomix.pregelix.io.VertexValueWritable;
+import edu.uci.ics.genomix.pregelix.io.VertexValueWritable.State;
+import edu.uci.ics.genomix.pregelix.io.message.MessageWritable;
+import edu.uci.ics.genomix.pregelix.operator.BasicGraphCleanVertex;
+import edu.uci.ics.genomix.pregelix.operator.aggregator.StatisticsAggregator;
+import edu.uci.ics.genomix.pregelix.type.MessageFlag;
+import edu.uci.ics.genomix.type.VKmerBytesWritable;
+
+public class SymmetryCheckerVertex extends
+ BasicGraphCleanVertex<VertexValueWritable, MessageWritable> {
+
+ @Override
+ public void initVertex() {
+ super.initVertex();
+ if(incomingMsg == null)
+ incomingMsg = new MessageWritable();
+ if(outgoingMsg == null)
+ outgoingMsg = new MessageWritable();
+ else
+ outgoingMsg.reset();
+ if(destVertexId == null)
+ destVertexId = new VKmerBytesWritable();
+ if(getSuperstep() == 1)
+ StatisticsAggregator.preGlobalCounters.clear();
+// else
+// StatisticsAggregator.preGlobalCounters = BasicGraphCleanVertex.readStatisticsCounterResult(getContext().getConfiguration());
+ counters.clear();
+ getVertexValue().getCounters().clear();
+ outFlag = 0;
+ }
+
+ @Override
+ public void compute(Iterator<MessageWritable> msgIterator) throws Exception {
+ initVertex();
+ if(getSuperstep() == 1){
+ sendSettledMsgToAllNeighborNodes(getVertexValue());
+ voteToHalt();
+ } else if(getSuperstep() == 2){
+ //check if the corresponding edge exists
+ while(msgIterator.hasNext()){
+ incomingMsg = msgIterator.next();
+ byte meToNeighborDir = (byte) (incomingMsg.getFlag() & MessageFlag.DIR_MASK);
+ byte neighborToMeDir = mirrorDirection(meToNeighborDir);
+ boolean exist = getVertexValue().getEdgeList(neighborToMeDir).contains(incomingMsg.getSourceVertexId());
+ if(!exist){
+ getVertexValue().setState(State.IS_ERROR);
+ }
+ }
+ voteToHalt();
+ }
+ }
+
+}
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/format/CheckerOutputFormat.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/format/CheckerOutputFormat.java
new file mode 100644
index 0000000..e562559
--- /dev/null
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/format/CheckerOutputFormat.java
@@ -0,0 +1,44 @@
+package edu.uci.ics.genomix.pregelix.format;
+
+import java.io.IOException;
+
+import org.apache.hadoop.io.NullWritable;
+import org.apache.hadoop.mapreduce.RecordWriter;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+
+import edu.uci.ics.genomix.pregelix.api.io.binary.GraphCleanVertexOutputFormat;
+import edu.uci.ics.genomix.pregelix.io.VertexValueWritable;
+import edu.uci.ics.genomix.pregelix.io.VertexValueWritable.State;
+import edu.uci.ics.genomix.type.VKmerBytesWritable;
+import edu.uci.ics.pregelix.api.graph.Vertex;
+import edu.uci.ics.pregelix.api.io.VertexWriter;
+
+public class CheckerOutputFormat extends
+ GraphCleanVertexOutputFormat<VKmerBytesWritable, VertexValueWritable, NullWritable> {
+
+ @Override
+ public VertexWriter<VKmerBytesWritable, VertexValueWritable, NullWritable> createVertexWriter(
+ TaskAttemptContext context) throws IOException, InterruptedException {
+ @SuppressWarnings("unchecked")
+ RecordWriter<VKmerBytesWritable, VertexValueWritable> recordWriter = binaryOutputFormat.getRecordWriter(context);
+ return new BinaryLoadGraphVertexWriter(recordWriter);
+ }
+
+ /**
+ * Simple VertexWriter that supports {@link BinaryLoadGraphVertex}
+ */
+ public static class BinaryLoadGraphVertexWriter extends
+ BinaryVertexWriter<VKmerBytesWritable, VertexValueWritable, NullWritable> {
+ public BinaryLoadGraphVertexWriter(RecordWriter<VKmerBytesWritable, VertexValueWritable> lineRecordWriter) {
+ super(lineRecordWriter);
+ }
+
+ @Override
+ public void writeVertex(Vertex<VKmerBytesWritable, VertexValueWritable, NullWritable, ?> vertex)
+ throws IOException, InterruptedException {
+ byte state = (byte)(vertex.getVertexValue().getState() & State.VERTEX_MASK);
+ if(state == State.IS_ERROR)
+ getRecordWriter().write(vertex.getVertexId(), vertex.getVertexValue());
+ }
+ }
+}
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/VertexValueWritable.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/VertexValueWritable.java
index 303d9b7..b8f768d 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/VertexValueWritable.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/VertexValueWritable.java
@@ -66,6 +66,7 @@
public static final byte IS_HALT = 0b100 << 3;
public static final byte IS_DEAD = 0b101 << 3;
+ public static final byte IS_ERROR = 0b110 << 3;
public static final byte VERTEX_MASK = 0b111 << 3;
public static final byte VERTEX_CLEAR = (byte)1000111;
diff --git a/genomix/genomix-pregelix/src/test/java/edu/uci/ics/genomix/pregelix/JobGen/JobGenerator.java b/genomix/genomix-pregelix/src/test/java/edu/uci/ics/genomix/pregelix/JobGen/JobGenerator.java
index d8c6bb0..08a7dab 100644
--- a/genomix/genomix-pregelix/src/test/java/edu/uci/ics/genomix/pregelix/JobGen/JobGenerator.java
+++ b/genomix/genomix-pregelix/src/test/java/edu/uci/ics/genomix/pregelix/JobGen/JobGenerator.java
@@ -5,6 +5,8 @@
import java.io.IOException;
import edu.uci.ics.genomix.config.GenomixJobConf;
+import edu.uci.ics.genomix.pregelix.checker.SymmetryCheckerVertex;
+import edu.uci.ics.genomix.pregelix.format.CheckerOutputFormat;
import edu.uci.ics.genomix.pregelix.format.GraphCleanInputFormat;
import edu.uci.ics.genomix.pregelix.format.GraphCleanOutputFormat;
import edu.uci.ics.genomix.pregelix.format.InitialGraphCleanInputFormat;
@@ -302,6 +304,23 @@
+ "ScaffoldingGraph.xml");
}
+ private static void generateSymmetryCheckerGraphJob(String jobName, String outputPath) throws IOException {
+ PregelixJob job = new PregelixJob(new GenomixJobConf(3), jobName);
+ job.setVertexClass(SymmetryCheckerVertex.class);
+ job.setGlobalAggregatorClass(StatisticsAggregator.class);
+ job.setVertexInputFormatClass(InitialGraphCleanInputFormat.class);
+ job.setVertexOutputFormatClass(CheckerOutputFormat.class);
+ job.setDynamicVertexValueSize(true);
+ job.setOutputKeyClass(VKmerBytesWritable.class);
+ job.setOutputValueClass(VertexValueWritable.class);
+ job.getConfiguration().writeXml(new FileOutputStream(new File(outputPath)));
+ }
+
+ private static void genSymmetryCheckerGraph() throws IOException {
+ generateSymmetryCheckerGraphJob("SymmetryCheckerGraph", outputBase
+ + "SymmetryCheckerGraph.xml");
+ }
+
public static void main(String[] args) throws IOException {
genUnrollTandemRepeatGraph();
genMapReduceGraph();
@@ -318,6 +337,7 @@
genSplitRepeatGraph();
getBFSTraverseGraph();
genScaffoldingGraph();
+ genSymmetryCheckerGraph();
}
}
diff --git a/genomix/genomix-pregelix/src/test/java/edu/uci/ics/genomix/pregelix/JobRun/PathMergeTestSuite.java b/genomix/genomix-pregelix/src/test/java/edu/uci/ics/genomix/pregelix/JobRun/PathMergeTestSuite.java
index ff6bb69..6ff2e26 100644
--- a/genomix/genomix-pregelix/src/test/java/edu/uci/ics/genomix/pregelix/JobRun/PathMergeTestSuite.java
+++ b/genomix/genomix-pregelix/src/test/java/edu/uci/ics/genomix/pregelix/JobRun/PathMergeTestSuite.java
@@ -6,7 +6,7 @@
public static Test suite() throws Exception {
String pattern ="PathMerge";
- String testSet[] = {"same"
+ String testSet[] = {"sameWithEdge"
// "2", "3", "4", "5", "6", "7", "8", "9", "head_6", "head_7",
// "P2_3", "P2_4", "P2_5", "P2_6", "P2_7", "P2_8",
// "LeftAdj", "RightAdj",
diff --git a/genomix/genomix-pregelix/src/test/java/edu/uci/ics/genomix/pregelix/JobRun/SymmetryCheckerTestSuite.java b/genomix/genomix-pregelix/src/test/java/edu/uci/ics/genomix/pregelix/JobRun/SymmetryCheckerTestSuite.java
new file mode 100644
index 0000000..00c0414
--- /dev/null
+++ b/genomix/genomix-pregelix/src/test/java/edu/uci/ics/genomix/pregelix/JobRun/SymmetryCheckerTestSuite.java
@@ -0,0 +1,14 @@
+package edu.uci.ics.genomix.pregelix.JobRun;
+
+import junit.framework.Test;
+
+public class SymmetryCheckerTestSuite extends BasicGraphCleanTestSuite{
+
+ public static Test suite() throws Exception {
+ String pattern ="SymmetryChecker";
+ String testSet[] = {"2"};
+ init(pattern, testSet);
+ BasicGraphCleanTestSuite testSuite = new BasicGraphCleanTestSuite();
+ return makeTestSuite(testSuite);
+ }
+}
diff --git a/genomix/genomix-pregelix/src/test/resources/only_SymmetryChecker.txt b/genomix/genomix-pregelix/src/test/resources/only_SymmetryChecker.txt
new file mode 100644
index 0000000..e19a09b
--- /dev/null
+++ b/genomix/genomix-pregelix/src/test/resources/only_SymmetryChecker.txt
@@ -0,0 +1 @@
+SymmetryCheckerGraph.xml