[med-svn] r1725 - in trunk/packages/plink/trunk: . .pc .pc/gcc43.patch debian debian/patches

smoe-guest at alioth.debian.org smoe-guest at alioth.debian.org
Wed Apr 9 09:43:12 UTC 2008


Author: smoe-guest
Date: 2008-04-09 09:43:11 +0000 (Wed, 09 Apr 2008)
New Revision: 1725

Added:
   trunk/packages/plink/trunk/.pc/
   trunk/packages/plink/trunk/.pc/.version
   trunk/packages/plink/trunk/.pc/applied-patches
   trunk/packages/plink/trunk/.pc/gcc43.patch/
   trunk/packages/plink/trunk/.pc/gcc43.patch/Makefile
   trunk/packages/plink/trunk/.pc/gcc43.patch/clumpld.cpp
   trunk/packages/plink/trunk/.pc/gcc43.patch/filters.cpp
   trunk/packages/plink/trunk/.pc/gcc43.patch/fisher.cpp
   trunk/packages/plink/trunk/.pc/gcc43.patch/nlist.cpp
   trunk/packages/plink/trunk/.pc/gcc43.patch/parse.cpp
   trunk/packages/plink/trunk/.pc/gcc43.patch/perm.cpp
   trunk/packages/plink/trunk/.pc/gcc43.patch/prephap.cpp
   trunk/packages/plink/trunk/.pc/gcc43.patch/proxy.cpp
   trunk/packages/plink/trunk/debian/
   trunk/packages/plink/trunk/debian/README.Debian
   trunk/packages/plink/trunk/debian/changelog
   trunk/packages/plink/trunk/debian/control
   trunk/packages/plink/trunk/debian/copyright
   trunk/packages/plink/trunk/debian/dirs
   trunk/packages/plink/trunk/debian/docs
   trunk/packages/plink/trunk/debian/manpage.sgml.ex
   trunk/packages/plink/trunk/debian/manpage.xml.ex
   trunk/packages/plink/trunk/debian/menu.ex
   trunk/packages/plink/trunk/debian/patches/
   trunk/packages/plink/trunk/debian/patches/gcc43.patch
   trunk/packages/plink/trunk/debian/patches/series
   trunk/packages/plink/trunk/debian/plink-default.ex
   trunk/packages/plink/trunk/debian/plink.1
   trunk/packages/plink/trunk/debian/plink.doc-base.EX
   trunk/packages/plink/trunk/debian/plink.install
   trunk/packages/plink/trunk/debian/rules
   trunk/packages/plink/trunk/debian/watch
   trunk/packages/plink/trunk/plink.log
Modified:
   trunk/packages/plink/trunk/Makefile
   trunk/packages/plink/trunk/clumpld.cpp
   trunk/packages/plink/trunk/filters.cpp
   trunk/packages/plink/trunk/fisher.cpp
   trunk/packages/plink/trunk/nlist.cpp
   trunk/packages/plink/trunk/parse.cpp
   trunk/packages/plink/trunk/perm.cpp
   trunk/packages/plink/trunk/prephap.cpp
   trunk/packages/plink/trunk/proxy.cpp
Log:
[svn-inject] Applying Debian modifications to trunk

Added: trunk/packages/plink/trunk/.pc/.version
===================================================================
--- trunk/packages/plink/trunk/.pc/.version	                        (rev 0)
+++ trunk/packages/plink/trunk/.pc/.version	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1 @@
+2

Added: trunk/packages/plink/trunk/.pc/applied-patches
===================================================================
--- trunk/packages/plink/trunk/.pc/applied-patches	                        (rev 0)
+++ trunk/packages/plink/trunk/.pc/applied-patches	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1 @@
+gcc43.patch

Added: trunk/packages/plink/trunk/.pc/gcc43.patch/Makefile
===================================================================
--- trunk/packages/plink/trunk/.pc/gcc43.patch/Makefile	                        (rev 0)
+++ trunk/packages/plink/trunk/.pc/gcc43.patch/Makefile	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,117 @@
+# -----------------------------------------------------------------#   Makefile for PLINK 
+#   
+#   Supported platforms
+#       Unix / Linux                LINUX
+#       Windows                     WIN
+#       Mac                         MAC
+#       Solaris                     SOLARIS
+#  
+#   Compilation options
+#       R plugins                   WITH_R_PLUGINS
+#       Web-based version check     WITH_WEBCHECK
+#       Ensure 32-bit binary        FORCE_32BIT 
+#
+# ---------------------------------------------------------------------
+
+# Set this variable to either UNIX, MAC or WIN
+SYS = UNIX
+
+# Leave blank after "=" to disable; put "= 1" to enable
+WITH_R_PLUGINS = 1
+WITH_WEBCHECK = 1
+FORCE_32BIT = 
+
+# Put C++ compiler here; Windows has it's own specific version
+CXX_UNIX = g++
+CXX_WIN = c:\bin\mingw\bin\mingw32-g++.exe
+
+# Any other compiler flags here ( -Wall, -g, etc)
+CXXFLAGS = 
+
+# --------------------------------------------------------------------
+# Do not edit below this line
+# --------------------------------------------------------------------
+
+CXXFLAGS += -O3 -I.
+OUTPUT = plink
+
+# Some system specific flags
+
+ifeq ($(SYS),WIN)
+ CXXFLAGS += -DWIN -static
+ CXX = $(CXX_WIN)
+endif
+
+ifeq ($(SYS),UNIX)
+ CXXFLAGS += -DUNIX -static
+ CXX = $(CXX_UNIX)
+endif
+
+ifeq ($(SYS),MAC)
+ CXXFLAGS += -DUNIX -Dfopen64=fopen
+ CXX = $(CXX_UNIX)
+endif
+
+ifeq ($(SYS),SOLARIS)
+ CXX = $(CXX_UNIX)
+endif
+
+ifdef FORCE_32BIT
+ CXXFLAGS += -m32
+endif
+
+# Flags for web-based version check
+
+ifdef WITH_WEBCHECK
+ifeq ($(SYS),WIN)
+ LIB += -lwsock32
+endif
+else
+ CXXFLAGS += -DSKIP
+endif
+
+
+
+SRC = plink.cpp options.cpp input.cpp binput.cpp tinput.cpp genome.cpp	\
+helper.cpp filters.cpp locus.cpp multi.cpp crandom.cpp cluster.cpp	\
+mds.cpp output.cpp informative.cpp assoc.cpp epi.cpp prephap.cpp	\
+phase.cpp trio.cpp tdt.cpp sharing.cpp genepi.cpp sets.cpp perm.cpp	\
+mh.cpp genedrop.cpp gxe.cpp merge.cpp hotel.cpp multiple.cpp		\
+haploCC.cpp haploTDT.cpp poo.cpp webcheck.cpp qfam.cpp linear.cpp	\
+bmerge.cpp parse.cpp mishap.cpp legacy.cpp homozyg.cpp segment.cpp	\
+model.cpp logistic.cpp glm.cpp dcdflib.cpp rarer.cpp dfam.cpp		\
+fisher.cpp linput.cpp sockets.cpp lookup.cpp proxy.cpp pdriver.cpp	\
+haploQTL.cpp haplohelper.cpp haplowindow.cpp genogroup.cpp		\
+nonfounderphasing.cpp clumpld.cpp genoerr.cpp em.cpp impute.cpp		\
+metaem.cpp profile.cpp nlist.cpp whap.cpp simul.cpp gvar.cpp cnv.cpp
+
+HDR = plink.h options.h helper.h crandom.h sets.h phase.h perm.h	\
+model.h linear.h logistic.h dcdflib.h ipmpar.h cdflib.h fisher.h	\
+sockets.h haplowindow.h genogroup.h clumpld.h nlist.h whap.h gvar.h
+
+ifdef WITH_R_PLUGINS
+CXXFLAGS += -DWITH_R_PLUGINS
+HDR += sisocks.h Rsrv.h Rconnection.h config.h
+SRC += r.cpp Rconnection.cpp
+LIB += -ldl -lcrypt
+endif
+
+OBJ = $(SRC:.cpp=.o)
+
+all : $(OUTPUT) 
+
+$(OUTPUT) :
+	$(CXX) $(CXXFLAGS) -o $(OUTPUT) $(OBJ) $(LIB) 
+
+$(OBJ) : $(HDR)
+
+.cpp.o : 
+	$(CXX) $(CXXFLAGS) -c $*.cpp
+.SUFFIXES : .cpp .c .o $(SUFFIXES)
+
+$(OUTPUT) : $(OBJ)
+
+FORCE:
+
+clean:
+	rm -f *.o *~

Added: trunk/packages/plink/trunk/.pc/gcc43.patch/clumpld.cpp
===================================================================
--- trunk/packages/plink/trunk/.pc/gcc43.patch/clumpld.cpp	                        (rev 0)
+++ trunk/packages/plink/trunk/.pc/gcc43.patch/clumpld.cpp	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,810 @@
+
+
+//////////////////////////////////////////////////////////////////
+//                                                              //
+//           PLINK (c) 2005-2007 Shaun Purcell                  //
+//                                                              //
+// This file is distributed under the GNU General Public        //
+// License, Version 2.  Please see the file COPYING for more    //
+// details                                                      //
+//                                                              //
+//////////////////////////////////////////////////////////////////
+
+
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <sstream>
+
+#include "clumpld.h"
+#include "phase.h"
+#include "options.h"
+#include "plink.h"
+
+
+//////////////////////////////////////////////////
+// Set user-defined parameters within constructor
+
+clump_LD::clump_LD(Plink * pp,
+		   HaploPhase * hp_,
+		   double sig, 
+		   double dist, 
+		   double secondp, 
+		   float r2c)
+{
+  P = pp;
+  hp = hp_;
+  pval_cutoff = sig;
+  ld_distance = dist;
+  second_pval_cutoff = secondp;
+  r2_cutoff = r2c;  
+  
+}
+
+
+/////////////
+// accessors
+
+void clump_LD::set_pval( double sig ){
+  pval_cutoff = sig;
+}
+
+void clump_LD::set_second_pval( double secondp ){
+  second_pval_cutoff = secondp;
+}
+
+void clump_LD::set_ld( double dist ){
+  ld_distance = dist;
+}
+
+void clump_LD::set_r2( double r2c ){
+  r2_cutoff = r2c;
+}
+
+
+//////////////////////////////////////////////////
+// read association file and pull out significant 
+// results sort by pvalue
+
+vector<ResultTrio> clump_LD::read_assoc_file(string fileList)
+{
+  
+  vector<ResultTrio> sp;
+
+  // We may be reading a single file, or more than one file
+  fileList = searchAndReplace(fileList,","," ");
+  
+  // Tokenize
+  filename.clear();
+  string buf; 
+  stringstream ss(fileList);
+  while (ss >> buf)
+    filename.push_back(buf);
+  
+  // Read each file
+  
+  for (int f=0; f<filename.size(); f++)
+    {
+
+      checkFileExists(filename[f]);
+      ifstream RESIN( filename[f].c_str(), ios::in );
+
+      int snp_column = -1;
+      int pval_column = -1;
+      vector<int> annot_field;
+
+      // Get header row
+      
+      char cline[par::MAX_LINE_LENGTH];
+      RESIN.getline(cline,par::MAX_LINE_LENGTH,'\n');
+      
+      string sline = cline;
+      if (sline=="") 
+	error("Problem reading [ " + par::clumpld_results + " ]\n");
+      
+      vector<string> tok_annot;
+
+      if ( par::clumpld_annot )
+	{
+	  string afields = searchAndReplace(par::clumpld_annot_fields,","," ");
+  	  string buf; 
+	  stringstream ss(afields);
+	  while (ss >> buf)
+	    tok_annot.push_back(buf);	 
+	}
+
+      string buf; 
+      stringstream ss(sline); 
+      vector<string> tokens; 
+      while (ss >> buf)
+	tokens.push_back(buf);
+      
+      for (int i=0; i<tokens.size(); i++)
+	{
+	  if ( tokens[i] == "SNP" )
+	    snp_column = i;
+	  
+	  if ( tokens[i] == par::clumpld_column )
+	    pval_column = i;	  
+
+	  if ( par::clumpld_annot ) 
+	    for ( int f=0; f<tok_annot.size(); f++)
+	      if ( tokens[i] == tok_annot[f] )
+		annot_field.push_back(i);
+	}
+      
+      
+      //////////////////////////////////////
+      // Did we find the necessary columns?
+      
+      if ( snp_column < 0 || pval_column < 0 )
+	{
+	  error("Could not find [" + par::clumpld_column 
+		+ "] as given in --clump-field\n");
+	}
+      
+      P->printLOG("Reading results for clumping from [ "
+		  + filename[f] + " ]\n");
+      P->printLOG("Extracting fields SNP and " 
+		  + par::clumpld_column + "\n");
+
+      while (!RESIN.eof())
+	{
+	  
+	  char cline[par::MAX_LINE_LENGTH];
+	  RESIN.getline(cline,par::MAX_LINE_LENGTH,'\n');
+	  
+	  string sline = cline;
+	  if (sline=="") 
+	    continue;
+	  
+	  string buf; 
+	  stringstream ss(sline); 
+	  vector<string> tokens; 
+	  while (ss >> buf)
+	    tokens.push_back(buf);
+	  
+	  if ( tokens.size() <= snp_column ||
+	       tokens.size() <= pval_column )
+	    continue;
+	  
+	  ResultTrio pt;
+
+	  // Keep track of which file this is from
+	  pt.f = f+1;
+
+	  if ( ! from_string<double>( pt.p, tokens[pval_column] , std::dec))
+	    continue;
+	  
+	  pt.s = tokens[snp_column];
+	  
+	  // Create clumped vector, based just on SNP name
+	  
+	  if( pt.p <= pval_cutoff )
+	    clumped.insert(make_pair(pt.s,false));
+	  
+	  ClumpPair cp;
+	  cp.snp = pt.s;
+	  cp.f = f+1;
+	  
+	  ClumpResults cr;
+	  cr.p = pt.p;
+	  cr.annot = "";
+	  if ( par::clumpld_annot )
+	    {
+	      for (int f=0; f<annot_field.size(); f++)
+		{
+		  cr.annot += tokens[annot_field[f]];
+		  if ( f < annot_field.size() - 1 )
+		    cr.annot += ", ";
+		}
+	    }
+
+	  assoc_results.insert( make_pair( cp, cr ));
+	  sp.push_back(pt);
+	  
+	}
+      
+      RESIN.close();
+
+      // Read in next results file
+    }
+  
+  sort(sp.begin(), sp.end());
+  return sp;
+}
+
+
+///////////////////////////////
+// Perform clumping operation
+
+void clump_LD::clump()
+{
+  
+  P->printLOG("\nWriting clumped results file to [ " + 
+	      par::output_file_name + ".clumped ]\n");
+
+  P->printLOG("Parameters for --clump:\n");
+  P->printLOG("          p-value threshold for index SNPs = " 
+	      + dbl2str(pval_cutoff) + "\n");
+
+  P->printLOG("      Physical (kb) threshold for clumping = " 
+	      + dbl2str(ld_distance/1000.0) + "\n");
+
+  P->printLOG("     LD (r-squared) threshold for clumping = " 
+	      + dbl2str(r2_cutoff) + "\n");
+
+  P->printLOG("        p-value threshold for clumped SNPs = " 
+	      + dbl2str(second_pval_cutoff) + "\n");
+
+
+  if ( par::clumpld_annot )
+    P->printLOG("Including annotation fields: " + par::clumpld_annot_fields +"\n");
+
+  vector<ResultTrio> sp = read_assoc_file( par::clumpld_results );
+
+  if ( par::clumpld_index1 )
+    P->printLOG("Indexing only on [ " + filename[0] + " ]\n");
+  else
+    P->printLOG("Indexing on all files\n");
+
+  if ( par::clumpld_only_show_replications )
+    P->printLOG("Only showing cross-file clumps\n");
+
+  int zero, one, two, three, four;
+  map<string,int> mlocus;
+  map<int2,double> grouped_snps;
+
+  ofstream CLMP;
+  CLMP.open( (par::output_file_name + ".clumped").c_str() , ios::out);
+  CLMP.precision(3);
+  CLMP.setf(ios::scientific);
+
+  string vmessage;
+
+  /////////////////
+  // Output header
+
+  if ( ! par::clumpld_verbose )
+    CLMP << setw(4) << "CHR" << " "
+	 << setw(4) << "F" << " "	 
+	 << setw(par::pp_maxsnp) << "SNP" << " " 
+	 << setw(10) << "BP" << " "
+	 << setw(8) << "P" << " " 
+	 << setw(8) << "TOTAL" << " "
+	 << setw(6) << "NSIG" << " "
+	 << setw(6) << "S05" << " "
+	 << setw(6) << "S01" << " "
+	 << setw(6) << "S001" << " "
+	 << setw(6) << "S0001" << " "
+	 << setw(6) << "SP2" << "\n";
+
+
+  //////////////////
+  // Build SNP map
+  
+  for (int l=0; l<P->nl_all; l++)
+    mlocus.insert(make_pair(P->locus[l]->name, l));
+  
+  if (sp.size()==0)
+    {
+      P->printLOG("No significant results given --clump parameters\n");
+      return;
+    }
+  
+  
+  
+  ////////////////////////////////////////////////
+  // Iterate through all association results by 
+  // decreasing p-value until cutoff is reached
+
+  int clumpCount = 0;
+
+  for (int i = 0; i < sp.size(); i++)
+    {
+
+      zero=one=two=three=four=0;
+      
+      ////////////////////////////////////
+      // End if p-value cutoff is reached
+      
+      if( sp[i].p > pval_cutoff )
+	break;
+      
+
+      //////////////////////////////////
+      // Skip already clumped this SNP
+      
+      if( clumped[sp[i].s] )
+	continue;
+      
+
+      /////////////////////////////////////////////
+      // Are we only indexing based on first file?
+
+      if ( par::clumpld_index1 && sp[i].f > 1 ) 
+	continue;
+
+
+     ///////////////////////////////////////////
+      // Make sure associated SNP is in SNP map
+      
+      map<string,int>::iterator ilocus;
+      ilocus = mlocus.find(sp[i].s);
+      int l = -1;
+      if (ilocus != mlocus.end())
+	{
+	  l = ilocus->second;
+	}
+      else 
+	{
+	  
+	  if ( !par::clumpld_verbose ) 
+	    CLMP << setw(4) << "NA" << " "
+		 << setw(4) << "NA" << " "
+		 << setw(par::pp_maxsnp) << sp[i].s << " "
+		 << setw(10) << "NA" << " "
+		 << setw(10) << sp[i].p << " " 
+		 << setw(8) << "NA" << " " 
+		 << setw(6) << "NA" << " " 
+		 << setw(6) << "NA" << " " 
+		 << setw(6) << "NA" << " " 
+		 << setw(6) << "NA" << " " 
+		 << setw(6) << "NA" << " "
+		 << setw(6) << "NA" << "\n";
+	  else
+	    vmessage += sp[i].s + " not found in dataset\n";
+
+	  continue;
+	}
+
+
+      ///////////////////////////////
+      // Check all SNPs in LD range
+      
+      // Set at reference SNP, l, and move out
+      // left and right (l1,l2)
+
+      int l1 = l; 
+      int l2 = l;
+      
+      // If multiple files, allow for self comparison also
+      if ( filename.size()>1 ) --l1;
+
+      set<string> willClump;
+
+      map<int,string> inPhaseAllele;
+
+      while(1)
+	{
+
+	  bool failed1 = false, failed2 = false;
+	  
+	  // Expand outwards to physical limits/SNP sets
+	  
+	  // Moving right
+
+	  if( l1 < P->locus.size()-1 )
+	    {
+	      // Advance a position
+	      l1++; 
+
+	      double r2a = -1;
+	      
+	      // Compute r-squared if this SNP is close
+	      // enough to the index SNP, physically
+	      
+	      if( P->locus[l1]->chr == P->locus[l]->chr && 
+		  P->locus[l1]->bp - P->locus[l]->bp < ld_distance )
+		r2a = hp->rsq( l, l1 );
+	      else
+		failed1 = true;
+
+
+	      //////////////////////////////////
+	      // Skip already clumped this SNP
+	      
+	      if( par::clumpld_indep && clumped[ P->locus[l1]->name ] )
+ 		  continue;
+	      
+	      // If in LD with association result
+	      
+	      if( r2a > r2_cutoff )
+		{
+		  
+		  // Record which alleles are correlated
+
+		  inPhaseAllele.insert(make_pair(l1, allelePairs(l,l1)));
+
+
+		  // Record that this SNP has been clumped
+
+		  willClump.insert(P->locus[l1]->name);
+		  
+		  // Now look at the assocations (in the multiple files) 
+		  // with this SNP
+			      
+		  for (int f=1; f<=filename.size(); f++)
+		    {
+		      ClumpPair result;
+		      result.snp = P->locus[l1]->name;
+		      result.f = f;
+		      
+		      // Do not clump with self
+		      if ( l == l1 && f == sp[i].f )
+			continue;
+		      
+		      // Result not found
+		      if ( assoc_results.find(result) == assoc_results.end() )
+			continue;
+
+		      double pval = assoc_results[result].p;
+ 
+		      if( pval < second_pval_cutoff )
+			{
+			  int2 t(l1,f);
+			  grouped_snps.insert(make_pair(t,r2a));
+			}
+
+		      if( pval < .0001 )
+			four++;
+		      else
+			if( pval < .001 )
+			  three++;
+			else
+			  if( pval < .01 )
+			    two++;
+			  else
+			    if( pval < .05 )
+			      one++;
+			    else
+			      zero++;
+		    }
+		}
+	    }
+	  else 
+	    failed1 = true;
+	      
+
+
+	  //////////////
+	  // Move left
+
+	  if( l2 > 0 )
+	    {
+	      l2--;
+	      
+	      double r2b = -1;
+	      
+
+	      if( P->locus[l2]->chr == P->locus[l]->chr && 
+		  P->locus[l]->bp - P->locus[l2]->bp < ld_distance )
+		r2b = hp->rsq( l, l2 );
+	      else
+		failed2 = true;
+	      
+
+	      //////////////////////////////////
+	      // Skip already clumped this SNP
+	      
+	      if( par::clumpld_indep && clumped[ P->locus[l2]->name ] )
+  		  continue;
+
+
+	      /////////////////////////////////////
+	      // Does this SNP meet r-sq threshold?
+	      
+	      if( r2b > r2_cutoff )
+		{
+		  
+		  // Find the allele in phase with rare allele for l
+		  
+		  inPhaseAllele.insert(make_pair(l2, allelePairs(l,l2)));
+
+
+		  // Record that this SNP is clumped
+
+		  willClump.insert(P->locus[l2]->name);
+		  
+		  // Now look at associations
+
+		  for (int f=1; f<=filename.size(); f++)
+		    {
+		      ClumpPair result;
+		      result.snp = P->locus[l2]->name;
+		      result.f = f;
+		      
+		      // Result not found
+		      if ( assoc_results.find(result) == assoc_results.end() )
+			continue;
+
+		      double pval = assoc_results[result].p;
+		      
+		      if( pval < second_pval_cutoff )
+			{
+			  int2 t(l2,f);
+			  grouped_snps.insert(make_pair(t,r2b));
+			}
+
+		      if( pval < .0001 )
+			four++;
+		      else
+			if( pval < .001 )
+			  three++;
+			else
+			  if( pval < .01 )
+			    two++;
+			  else
+			    if( pval < .05 )
+			      one++;
+			    else
+			      zero++;
+		    }
+		} 
+
+	    }
+	  else
+	    failed2 = true;
+	  
+	  
+	  // No point in looking further?
+
+	  if( failed1 && failed2 ) 
+	    break;	  
+	
+	}
+      
+
+      //////////////////////////////////////////////////////////
+      // Report results
+
+      // Are we only interested in cross-file clumpings?
+
+      if ( par::clumpld_only_show_replications )
+	{
+	  bool seen_replication = false;
+	  map<int2,double>::iterator gi = grouped_snps.begin();	  
+	  int cnt=0;
+	  int lastf;
+	  while( gi != grouped_snps.end() )
+	    {
+	      if ( cnt > 0 ) 
+		{
+		  if ( gi->first.p2 != lastf ) 
+		    seen_replication = true;
+		}	      
+	      lastf = gi->first.p2;
+	      ++cnt;
+	      ++gi;
+	    }
+
+	  // If no cross-file results, then do not report this 
+	  // clump -- clear all flags for it
+
+	  if ( ! seen_replication ) 
+	    {
+	      grouped_snps.clear();
+	      continue;
+	    }
+	}
+    
+      
+      // Indicate that this SNP has now been clumped
+      set<string>::iterator si = willClump.begin();
+      while ( si != willClump.end() )
+	{
+	  clumped[ *si ] = true;
+	  ++si;
+	}
+
+
+
+      int total = zero+one+two+three+four;
+      
+      if ( par::clumpld_verbose ) 
+	{
+	  // Repeat header
+	  CLMP << "\n"
+	       << setw(4) << "CHR" << " "
+	       << setw(4) << "F" << " "
+	       << setw(par::pp_maxsnp) << "SNP" << " " 
+	       << setw(10) << "BP" << " "
+	       << setw(10) << "P" << " " 
+	       << setw(8) << "TOTAL" << " "
+	       << setw(6) << "NSIG" << " "
+	       << setw(6) << "S05" << " "
+	       << setw(6) << "S01" << " "
+	       << setw(6) << "S001" << " "
+	       << setw(6) << "S0001" << "\n";	  
+	}
+
+      ClumpPair cp;
+      cp.snp = P->locus[l]->name;
+      cp.f = sp[i].f;
+
+      CLMP << setw(4) << P->locus[l]->chr << " " 
+	   << setw(4) << cp.f << " " 	   
+	   << setw(par::pp_maxsnp) << P->locus[l]->name << " " 
+	   << setw(10) << P->locus[l]->bp << " " 
+	   << setw(10) << assoc_results[cp].p << " " 
+	   << setw(8) << total << " " 
+	   << setw(6) << zero << " " 
+	   << setw(6) << one << " " 
+	   << setw(6) << two << " " 
+	   << setw(6) << three << " " 
+	   << setw(6) << four << " ";
+      
+      if ( par::clumpld_verbose ) 
+	{
+	  // Now list one per line, sorted by distance
+	  CLMP << "\n";
+	  if ( grouped_snps.size() > 0 ) 
+	    {
+
+	      CLMP << "\n" 
+		   << setw(4) << " " << " " 		   
+		   << setw(4) << " " << " " 		   
+		   << setw(par::pp_maxsnp) << " " << " "
+		   << setw(10) << "KB" << " "
+		   << setw(8) << "RSQ" << " "
+		   << setw(8) << "ALLELES" << " "
+		   << setw(4) << "F" << " "		   
+		   << setw(12) << "P" << " ";
+	      if ( par::clumpld_annot )
+		CLMP << setw(12) << "ANNOT" << "\n";
+	      else
+		CLMP << "\n";
+	      
+	      CLMP << setw(4) << "  (INDEX) " 
+		   << setw(par::pp_maxsnp) << P->locus[l]->name << " ";
+
+	      CLMP << setw(10) << (double)(P->locus[l]->bp - P->locus[l]->bp)/1000.0 << " ";
+
+	      CLMP << setw(8) << "1.000" << " "
+		   << setw(8) << P->locus[l]->allele1 << " "
+		   << setw(4) << sp[i].f << " " 		       
+		   << setw(12) << assoc_results[cp].p << " ";
+	      if ( par::clumpld_annot )
+		CLMP << setw(12) << assoc_results[cp].annot << "\n";
+	      else
+		CLMP << "\n";
+	      
+	      CLMP << "\n";
+
+
+	      //////////////////////////////////////////////////
+	      // Track if SNP info already listed in this group
+	      
+	      set<int> infoDisplayed;
+
+
+	      map<int2,double>::iterator gi = grouped_snps.begin();
+	      
+	      while( gi != grouped_snps.end() )
+		{
+		  
+		  int l0 = gi->first.p1;
+		  int f = gi->first.p2;
+
+		  ClumpPair cp;
+		  cp.snp = P->locus[l0]->name;
+		  cp.f = f;
+		  
+  
+		  if ( assoc_results.find(cp) != assoc_results.end() )
+		    {
+		      if ( infoDisplayed.find(l0) == infoDisplayed.end() )
+			{
+			  CLMP << setw(4) << " " << " "				   
+			       << setw(4) << " " << " "				   
+			       << setw(par::pp_maxsnp) << P->locus[l0]->name << " "
+			       << setw(10) << (double)(P->locus[l0]->bp - P->locus[l]->bp)/1000.0 << " ";
+			  
+			  CLMP.setf(ios::fixed);
+			  CLMP << setw(8) << gi->second << " ";
+			  CLMP.setf(ios::scientific);
+			  
+			  CLMP << setw(8) << inPhaseAllele.find(l0)->second << " "
+			       << setw(4) << f << " " 		       
+			       << setw(12) << assoc_results[cp].p << " ";
+			  if ( par::clumpld_annot )
+			    CLMP << setw(12) << assoc_results[cp].annot << "\n";
+			  else
+			    CLMP << "\n";
+			  
+			  infoDisplayed.insert(l0);
+			}
+		      else
+			{
+			  CLMP << setw(4) << " " << " "
+			       << setw(4) << " " << " "
+			       << setw(par::pp_maxsnp) << " " << " "
+			       << setw(10) << " " << " "
+			       << setw(8) << " " << " "
+			       << setw(8) << " " << " "
+			       << setw(4) << f << " " 		       
+			       << setw(12) << assoc_results[cp].p << " ";
+			  if ( par::clumpld_annot )
+			    CLMP << setw(12) << assoc_results[cp].annot << "\n";
+			  else
+			    CLMP << "\n";
+
+			}
+		    }
+		  		  
+		  gi++;
+		}
+	    }
+	}
+      else
+	{
+	  
+	  // Just list of SNP names
+	  if( grouped_snps.size() == 0 )
+	    CLMP << "NONE";
+	  
+	  map<int2,double>::iterator gi = grouped_snps.begin();
+          int j = 0;
+          while( gi != grouped_snps.end() )
+            {
+              CLMP << P->locus[ gi->first.p1 ]->name << "(" 
+		   << gi->first.p2 << ")";
+              if( j < grouped_snps.size()-1)
+                CLMP << ",";
+              j++;
+              gi++;
+            }
+	}
+
+      
+      if ( par::clumpld_verbose )
+	CLMP << "\n"
+	     << "------------------------------------------------------------------\n";
+
+      CLMP << "\n";
+      
+      if ( ! par::silent)
+	cout << "Formed " << ++clumpCount
+	     << " clumps of the top " 
+	     << i << " SNPs, so far            \r";
+      
+      grouped_snps.clear();
+
+
+      // Next SNP
+    }
+  
+  
+  if ( ! par::silent)
+    cout << "\n";
+  
+  CLMP << "\n" << vmessage << "\n";
+
+  CLMP.close();
+}
+
+
+
+string clump_LD::allelePairs(int l1, int l2)
+{
+  
+  // The first SNP is always the index SNP
+  // i.e. as we call rsq(l,l1) and rsq(l,l2) above
+
+  // Identify common/common haplotype
+
+  int ch = 0;
+  for (int h=0; h<hp->nh; h++)
+    if ( hp->haplotypeName(h) == P->locus[l1]->allele2 + P->locus[l2]->allele2 )
+      ch = h;
+  
+  // Is D positive or negative?
+  string s;
+
+  if ( hp->f[ch] > (1 - P->locus[l1]->freq)*(1 - P->locus[l2]->freq) )
+    s = P->locus[l1]->allele1 + P->locus[l2]->allele1 + "/" + P->locus[l1]->allele2 + P->locus[l2]->allele2;
+  else
+    s = P->locus[l1]->allele1 + P->locus[l2]->allele2 + "/" + P->locus[l1]->allele2 + P->locus[l2]->allele1;
+
+  return s;
+}

Added: trunk/packages/plink/trunk/.pc/gcc43.patch/filters.cpp
===================================================================
--- trunk/packages/plink/trunk/.pc/gcc43.patch/filters.cpp	                        (rev 0)
+++ trunk/packages/plink/trunk/.pc/gcc43.patch/filters.cpp	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,1177 @@
+
+
+//////////////////////////////////////////////////////////////////
+//                                                              //
+//           PLINK (c) 2005-2007 Shaun Purcell                  //
+//                                                              //
+// This file is distributed under the GNU General Public        //
+// License, Version 2.  Please see the file COPYING for more    //
+// details                                                      //
+//                                                              //
+//////////////////////////////////////////////////////////////////
+
+
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <sstream>
+#include <vector>
+#include <map>
+#include <cmath>
+#include <iterator>
+#include "plink.h"
+#include "options.h"
+#include "helper.h"
+
+#define MISSING(i,l) ( SNP[l]->one[i] && ( ! SNP[l]->two[i] ) ) 
+
+void Plink::filterSNPs()
+{
+
+
+  //////////////////////////////////////////////////////
+  // This functions applies the following filters and 
+  // functions:
+  
+  // Counts of number of founders, nonfounders 
+  // Per-individual genotyping rate
+  // Read in, or calculate, allele frequencies (and save these)
+  // Optionally write allele frequencies, then close
+  // Exclude SNPs with too many missing genotypes
+  // Identify/correct heterozygote haploid
+  // Identify SNPs with no founder genotypes
+  // Calculate/report/filter on HWE tests
+  // Calculate/report genotyping rate per SNP/per individual
+  // Filter on MAF 
+  // Remove filtered-out SNPs
+
+  
+  bool original_SNP_major = par::SNP_major;
+  
+  if ( ! par::SNP_major )
+    Ind2SNP();
+    
+
+  // Which SNPs to delete
+  vector<bool> del(locus.size(),false);
+
+  // Which individuals to delete
+  vector<bool> indel(sample.size(),false);
+  
+
+  //////////////////////////////////////////
+  // Display number of founders/nonfounders 
+
+  cnt_f=0;
+  vector<Individual*>::iterator person = sample.begin();
+  while ( person != sample.end() ) 
+    {  
+      if ( (*person)->founder ) cnt_f++;	    
+      person++;
+    }
+  printLOG(int2str(cnt_f)+" founders and "+int2str(n-cnt_f)+
+	   " non-founders found\n");
+
+  if (cnt_f<n) par::has_nonfounders = true;
+
+
+  ////////////////////////////////////////////
+  // If we have obligatory missing genotypes:
+  // ensure they really are missng
+  
+  if ( par::oblig_missing ) 
+    {
+      set<int2>::iterator p = oblig_missing.begin();
+      while ( p != oblig_missing.end() )
+	{
+	  int l = p->p1;
+	  int k = p->p2;
+
+	  for (int i=0; i<sample.size(); i++)
+	    {
+	      Individual * person = sample[i];
+	      if ( person->sol == k )
+		{
+		  SNP[l]->one[i] = true;
+		  SNP[l]->two[i] = false;
+		}
+	    }
+	  ++p;
+	}
+    }
+
+
+  /////////////////////////////////////////////////
+  // Remove individuals with too many missing calls
+  
+  double total_genotyping = 0;
+
+  if ( par::MAX_IND_MISSING < 1 )
+    {
+  
+      int n_removed = 0;
+      int n_orig = n;
+
+      // Consider each individual
+      if ( ! par::oblig_missing )
+	{
+	  for (int i=0;i<sample.size();i++)
+	    {
+	  
+	      // Sum missingness over all SNPs
+	      int m=0;       // Missing SNPs
+	      int nsnps=0;   // All non-obligatory missing SNPs
+	      
+	      nsnps = locus.size();
+	      for (int l=0; l<nsnps;l++)
+		if ( MISSING(i,l) ) m++;
+	    
+	      // Too much missingness?
+	      if ( (double)m/(double)nsnps > par::MAX_IND_MISSING )
+		{
+		  indel[i] = true;
+		  n_removed++;
+		}  	      
+	    } // next individual	  
+	}
+      else // ... allow oblig missing values
+	{
+	  for (int i=0;i<sample.size();i++)
+	    {	      
+	      
+	      // Sum missingness over all SNPs
+	      int m=0;       // Missing SNPs
+	      int nsnps=0;   // All non-obligatory missing SNPs
+	      
+	      for (int l=0; l<locus.size();l++)
+		{
+		  if ( ! obligMissing(i,l) )
+		    {
+		      if ( MISSING(i,l) )
+			++m;
+		      ++nsnps;
+		    }
+		}
+	      
+	      // Too much missingness?
+	      if ( (double)m/(double)nsnps > par::MAX_IND_MISSING )
+		{
+		  indel[i] = true;
+		  n_removed++;
+		}
+	      
+	    } // next individual
+	} // end if oblig-missing section
+      
+
+      ////////////////////////////////////////
+      // Save list of any removed individuals
+      
+      if (n_removed>0)
+	{
+	  string f = par::output_file_name + ".irem";
+	  printLOG("Writing list of removed individuals to [ " + f + " ]\n");	
+	  ofstream REM;
+	  REM.open(f.c_str(), ifstream::out);
+	  for (int i=0;i<sample.size();i++)
+	    if (indel[i])
+	      REM << sample[i]->fid << "\t" << sample[i]->iid << "\n";
+	  REM.close();      
+	  
+         
+	  // And now remove these individuals, so that 
+	  // SNP-based statistics are calculated with 
+	  // these samples already excluded
+	  
+	  n_removed = deleteIndividuals(indel);
+	  
+	}
+      
+      printLOG(int2str(n_removed)+" of "+int2str(n_orig));
+      printLOG(" individuals removed for low genotyping ( MIND > ");
+      printLOG(dbl2str(par::MAX_IND_MISSING)+" )\n");
+            
+      
+    } // end of remove people conditional
+
+ 
+
+  /////////////////////////////////
+  // Calculate or read from file? 
+
+  if (par::af_read)
+    {
+      checkFileExists(par::af_file);
+      printLOG( "Reading allele frequencies from [ " + par::af_file + " ] \n");
+      
+      // Make hash of original SNP names
+      map<string,int> mlocus;
+      map<string,int>::iterator ilocus;
+      
+      vector<Locus*>::iterator loc = locus.begin();
+      int l=0;
+      while ( loc != locus.end() ) 
+	{ 
+	  mlocus.insert(make_pair( (*loc)->name,l));
+	  loc++;
+	  l++;
+	}
+
+
+      // Read allele frequencies
+      ifstream FRQ;
+      FRQ.open(par::af_file.c_str());
+      FRQ.clear();
+      
+      string dum1, dum2, dum3, dum4, dum5, dum6;
+      string snpname;
+      double freq;
+      int nm;
+      
+      loc = locus.begin();
+      while ( loc != locus.end() ) 
+	{
+	  (*loc)->freq = -1;
+	  (*loc)->nm = 0;
+	  loc++;
+	}
+      
+      // Skip header line
+      FRQ >> dum1 >> dum2 >> dum3 >> dum4 >> dum5 >> dum6;
+
+      while(!FRQ.eof())
+	{
+
+	  char cline[256];
+	  FRQ.getline(cline,256,'\n');
+	  string sline = cline;
+	  if (sline=="") continue;
+	  stringstream ss(sline); 
+	  string buf; 
+	  vector<string> tokens; 
+	  while (ss >> buf)
+	    tokens.push_back(buf);
+	  if (tokens.size() == 0)
+	    continue;
+	  else if (tokens.size() != 6)
+	    error("Problem with allele frequency line: 6 fields required:\n"
+		  +sline+"\n");
+	  
+	  ilocus = mlocus.find(tokens[1]);
+	  if (ilocus != mlocus.end())
+	    {
+	      locus[ilocus->second]->freq = atof(tokens[4].c_str());    
+	      locus[ilocus->second]->nm = atoi(tokens[5].c_str());
+	    }
+	}
+      FRQ.clear();
+      FRQ.close();
+      
+    }
+  
+
+  /////////////////////////////////
+  // Calculate allele frequencies
+  
+  vector<string> hetlist(0);
+  
+  vector<bool>::iterator d = del.begin();
+  vector<Locus*>::iterator loc = locus.begin();
+  vector<CSNP*>::iterator s = SNP.begin();
+  int l = 0; // Main locus counter
+
+  int exc_maf = 0;
+  int exc_miss = 0;
+  
+  vector<Locus*> no_founders_found_list; 
+  
+  while ( loc != locus.end() ) 
+    {
+      
+      if (!par::af_read)      
+	{
+	  (*loc)->freq = 0;
+	  // count 1 per allele, for frequency
+	  (*loc)->nm = 0; 
+	}
+      
+      // count 1 per genotype, for missingness
+      int geno_nm = 0; 
+      
+      // count 1 per non-obligatory missing genotype 
+      // (or set to N individuals)
+      int geno_real = par::oblig_missing ? 0 : n ; 
+      
+      bool X = false;
+      bool haploid = false;
+      
+      // Determine type of SNP
+      if (par::chr_sex[(*loc)->chr]) X=true;
+      else if (par::chr_haploid[(*loc)->chr]) haploid=true;
+      
+      
+      ///////////////////////////////
+      // Iterate over each individual
+      
+      vector<bool>::iterator i1 = (*s)->one.begin();
+      vector<bool>::iterator i2 = (*s)->two.begin();
+      vector<Individual*>::iterator person = sample.begin();
+      int i = 0;
+
+      while ( person != sample.end() ) 
+	{
+	  
+	  bool s1 = *i1;
+	  bool s2 = *i2;
+	  
+	  // Check female Y genotypes
+	  if ( par::chr_Y[(*loc)->chr] && ! (*person)->sex )
+	    {
+	      // Set to missing, unless in a RECODE mode
+	      if ( ! par::preserve_all_genotypes )
+		{
+		  s1 = *i1 = true;
+		  s2 = *i2 = false;
+		}		  
+	    }
+	  
+	  // For haploid heterozygosity check, also consider all individuals
+	  if ( haploid || ( X && (*person)->sex ) )
+	    {
+	      if ( (!s1) && s2 )
+		{
+		  hetlist.push_back( (*person)->fid + "\t" + 
+				     (*person)->iid + "\t" + 
+				     (*loc)->name );
+		  
+		  // Set to missing, unless in a RECODE mode
+		  if ( ! par::preserve_all_genotypes )
+		    {
+		      *i1 = true;
+		      *i2 = false;
+		    }
+		}
+	    } 
+
+	  	  
+	  
+	  // For missing genotypes, consider all individuals
+	  if ( ! ( s1 && (!s2) ) ) geno_nm++;
+	  
+	  // But is this a real genotype in any case?
+	  if ( par::oblig_missing && ! obligMissing(i,l) )
+	    geno_real++;
+	  
+	  
+	  // Do not recount alleles if we have read in allele frequencies
+	  if (!par::af_read)
+	    {	      
+	      // For allele frequencies
+	      // only consider founders	
+	      if ( par::summ_nonfounders || (*person)->founder ) 
+		{
+		  
+		  if ( haploid || ( X && (*person)->sex ) )
+		    {
+		      
+		      //////////////////
+		      // Haploid counts
+		      
+		      // "1" allele count
+		      
+		      if ( (!s1) && (!s2) )   //  FF = hom(11)
+			{
+			  (*loc)->freq++;
+			  (*loc)->nm++;
+			}	
+		      else if ( s1 && s2 )   //  TT = hom(22)
+			{
+			  (*loc)->nm++;
+			}
+		      
+		    }
+		  else
+		    {
+		      
+		      //////////////////
+		      // Autosomal count
+		      
+		      // "1" allele count
+		      
+		      if (!s1)
+			{ 
+			  if (!s2) //   00 = hom(11)
+			    {
+			      (*loc)->freq+=2;
+			      (*loc)->nm+=2;
+			    }	
+			  else //   01 = het(12)
+			    {
+			      (*loc)->freq+=1;
+			      (*loc)->nm+=2;
+			    }
+			}
+		      else if ( s2 ) // 11 = hom(22)
+			{
+			  (*loc)->nm+=2;
+			}
+		    }
+		  
+		}
+	    }
+	  
+	  // Next individual
+	  person++;
+	  i++;
+	  i1++;
+	  i2++;
+	}
+      
+      
+      ////////////////////////////////
+      // Calculate allele frequencies
+      
+      if (!par::af_read)
+	{
+	  if ( par::af_count) // Allele counts...
+	    {
+	      // Use freq to store count (keep as is)	
+
+	      // Use "bp" to store number of allele 2
+	      (*loc)->bp = (long int)((*loc)->nm - (*loc)->freq);
+
+	      // Use "pos" to store number missing genotypes
+	      (*loc)->pos = geno_real - geno_nm;
+	    }
+	  else // ... or frequencies
+	    {		
+	      if ((*loc)->nm>0)
+		(*loc)->freq /= (double)(*loc)->nm;
+	      else
+		{
+		  (*loc)->freq = 1; 
+		  // If we aren't getting rid of it anyway
+		  if ( (double)geno_nm/(double)geno_real >= (1-par::MAX_GENO_MISSING))
+		    no_founders_found_list.push_back(*loc);
+		}
+	    }
+	}
+
+
+      //////////////////////////////////////////
+      // Record total proportion of missingness
+      
+      double snp_genotyping = n>0 ? (double)geno_nm/(double)geno_real : 0;
+      total_genotyping += snp_genotyping;
+
+
+      /////////////////////////////////////////////////
+      // Exclude if SNP has too many missing genotypes
+
+      if ( snp_genotyping < (1-par::MAX_GENO_MISSING) )
+	{	  
+	  *d = true;
+	  exc_miss++;
+	}
+      
+
+      ////////////////////////////////////////////////
+      // Make allele1 always the least common allele
+            
+      if ( (!par::af_count) && (*loc)->freq > 0.5 ) 
+	{
+	  
+	  // then we need to swap alleles
+
+	  (*loc)->freq = 1 - (*loc)->freq;
+	  
+	  string tmp = (*loc)->allele2;
+	  (*loc)->allele2 = (*loc)->allele1;
+	  (*loc)->allele1 = tmp;
+	  
+	  vector<bool>::iterator i1 = (*s)->one.begin();
+          vector<bool>::iterator i2 = (*s)->two.begin();
+
+          while ( i1 != (*s)->one.end() ) 
+	    {	      
+
+	      if ( (*i1) == (*i2) ) 
+		{
+		  *i1 = ! (*i1);
+		  *i2 = ! (*i2);
+		}
+	      
+	      i1++;
+	      i2++;
+	    }
+	  
+	}
+      
+      // Next SNP
+      ++d;
+      ++loc;
+      ++l;
+      ++s;
+    }
+  
+
+
+
+  /////////////////////////////////////////////////
+  // Save list of any heterozygous haploid alleles
+  
+  if (hetlist.size()>0)
+    {
+      printLOG(int2str( hetlist.size()) 
+	       + " heterozygous haploid genotypes called\n");
+      string f = par::output_file_name + ".hh";
+      printLOG("Writing list of heterozygous haploid genotypes to [ " 
+	       + f + " ]\n");
+      ofstream REM;
+      REM.open(f.c_str(), ifstream::out);
+      for (int i=0; i<hetlist.size(); i++)
+	REM << hetlist[i] << "\n";
+      REM.close();      
+    }
+  hetlist.clear();
+
+  
+
+  /////////////////////////////////////////////////
+  // Save list of SNPs with no founders observed
+  
+  if (no_founders_found_list.size()>0)
+    {
+      printLOG(int2str( no_founders_found_list.size()) 
+	       + " SNPs with no founder genotypes observed\n");
+      printLOG("Warning, MAF set to 0 for these SNPs (see --nonfounders)\n"); 
+      string f = par::output_file_name + ".nof";
+      printLOG( "Writing list of these SNPs to [ " + f + " ]\n");
+      ofstream NOF;
+      NOF.open(f.c_str(), ifstream::out);
+      for (int i=0; i<no_founders_found_list.size(); i++)
+	NOF << no_founders_found_list[i]->name << "\n";
+      NOF.close();      
+    }
+  no_founders_found_list.clear();
+
+
+  
+  //////////////////////////
+  // Write allele freq file
+  
+  if (par::af_write)
+    {
+      if (par::include_cluster_from_file)
+	calcStratifiedAlleleFreqs();
+      else
+	{
+	  ofstream FRQ;
+	  string f = par::output_file_name + ".frq";
+	  if (par::af_count) f += ".count";
+
+	  if (par::summ_nonfounders)
+	    printLOG("Writing allele frequencies (all individuals) to [ " 
+		     + f + " ] \n");
+	  else
+	    printLOG("Writing allele frequencies (founders-only) to [ " 
+		     + f + " ] \n");
+	  
+	  if (par::af_count)
+	    printLOG("Display counts rather than frequencies\n");
+
+	  FRQ.open(f.c_str(), ifstream::out);
+
+	  FRQ << setw(4) << "CHR" << " "
+	      << setw(par::pp_maxsnp) << "SNP" << " "
+	      << setw(4) << "A1" << " "
+	      << setw(4) << "A2" << " ";
+	  if (par::af_count)
+	    FRQ << setw(6) << "C1" << " "
+		<< setw(6) << "C2" << " "
+		<< setw(6) << "G0" << "\n";
+	  else
+	    FRQ << setw(12) << "MAF" << " " 
+		<< setw(8) << "NCHROBS" 
+		<< "\n";	  
+	  
+	  vector<Locus*>::iterator loc = locus.begin();
+	  while (loc != locus.end() )
+	    {
+	      string a1 = (*loc)->allele1;
+	      string a2 = (*loc)->allele2;
+	      if (a1=="") a1="0";
+	      if (a2=="") a2="0";
+	      FRQ << setw(4)  << (*loc)->chr  << " "
+		  << setw(par::pp_maxsnp) << (*loc)->name  << " "
+		  << setw(4)  << a1  << " "
+		  << setw(4)  << a2  << " ";
+
+	      if (par::af_count)
+		{
+		  FRQ << setw(6) << int( (*loc)->freq ) << " "
+		      << setw(6) << int( (*loc)->bp   ) << " " 
+		      << setw(6) << int( (*loc)->pos  ) << "\n";
+		}
+	      else
+		{
+		  if ( (*loc)->freq >= 0 )
+		    FRQ << setw(12) << (*loc)->freq << " ";
+		  else
+		    FRQ << setw(12) << "NA" << " ";
+		  FRQ << setw(8) << (*loc)->nm << "\n";
+		}
+	      loc++;
+	    }
+	  FRQ.close();
+	  
+	}
+      
+      // Close after we've done alle freqs,
+      shutdown();
+    }
+
+
+
+  /////////////////////////
+  // Write HWE statistics
+  
+  if (par::HWD_test || par::HWD_report)
+    {
+      
+      ofstream HWD;
+      if (par::HWD_report)
+	{
+	  
+	  if (par::summ_nonfounders)
+	    printLOG("Writing Hardy-Weinberg tests (all individuals) to [ " +
+		     par::output_file_name + ".hwe ] \n");
+	  else
+	    printLOG("Writing Hardy-Weinberg tests (founders-only) to [ " +
+		     par::output_file_name + ".hwe ] \n");
+	  
+	  string f = par::output_file_name + ".hwe";
+	  HWD.open(f.c_str(), ifstream::out);
+	  
+	  HWD.precision(4);
+	  
+	  HWD << setw(par::pp_maxsnp) << "SNP" << " "
+	      << setw(8) << "TEST" << " " 
+	      << setw(20) << "GENO" << " "
+	      << setw(8) << "O(HET)" << " "
+	      << setw(8) << "E(HET)" << " "
+	      << setw(12) << "P_HWD" << " "	      
+	      << "\n";
+	}
+      
+      int cnt=0, cnt_a=0, cnt_u=0;
+      
+
+      ////////////////////////
+      // Consider each locus
+      
+      vector<bool>::iterator d = del.begin();
+      vector<Locus*>::iterator loc = locus.begin();
+
+      for ( int l = 0 ; l < locus.size() ; l++ )
+	{
+	  
+	  // Compute p-values for HWE test in cases, controls & all
+	  
+	  // Only consider founders
+	  
+	  int a11, a12, a22;
+	  int u11, u12, u22;
+	  int b11, b12, b22;
+	  
+	  a11=a12=a22=0;
+	  u11=u12=u22=0;
+	  b11=b12=b22=0;
+	  
+	  bool X = false, haploid = false;
+	  if (par::chr_sex[(*loc)->chr]) X=true;
+	  else if (par::chr_haploid[(*loc)->chr]) haploid=true;
+	  
+	  
+	  ///////////////////////////////////////////////
+	  // Iterate over each individual, founders only
+	 
+	  for ( int i = 0 ; i < sample.size() ; i++ ) 
+	    {
+	      
+	      Individual * person = sample[i];
+
+	      ///////////////////////////////////////////////
+	      // Only consider founders, & diploid genotypes
+	      
+	      if ( par::summ_nonfounders || person->founder )
+		if ( ! ( haploid || ( X && person->sex ) ) )
+		  {	
+		    
+		    bool s1 = SNP[l]->one[i];
+		    bool s2 = SNP[l]->two[i];
+
+		    // Consider everybody, irrespective of phenotype
+		    // (QT, C/C or missing)
+		    
+		    if (!s1)
+		      { 
+			if (!s2) b11++;   //   00 = hom(11)
+			else b12++;       //   01 = het(12)
+		      }
+		    else if ( s2 ) b22++; // 11 = hom(22)
+		    
+		    
+		    if (par::bt)  // for binary trait, separately for cases/controls
+		      {
+			if (person->phenotype == 1)
+			  {
+			    
+			    if (!s1)
+			      { 
+				if (!s2) u11++;   //   00 = hom(11)
+				else u12++;       //   01 = het(12)
+			      }
+			    else if ( s2 ) u22++; //   11 = hom(22)
+			    
+			  }
+			else if (person->phenotype == 2)
+			  {
+			    if (!s1)
+			      { 
+				if (!s2) a11++;   //   00 = hom(11)
+			      else a12++;         //   01 = het(12)
+			      }
+			    else if ( s2 ) a22++; //   11 = hom(22)
+			  }
+			
+		      }
+		  }
+	    
+	      
+	      // Next individual
+	    }
+
+
+	  // Allele frequencies
+	  double afreq = 0, ufreq = 0, freq = 0;
+	  
+	  bool include_cases = true;
+	  bool include_controls = true;
+	  if (par::qt)
+	    freq = ( b11 + (double)b12/2.0 ) / (double)( b11+b12+b22 );
+	  else
+	    {
+	      afreq = ( a11 + (double)a12/2.0 ) / (double)( a11+a12+a22 );
+	      ufreq = ( u11 + (double)u12/2.0 ) / (double)( u11+u12+u22 );
+	      freq =  ( b11 + (double)b12/2.0 ) / (double)( b11+b12+b22 );
+
+	      if ( a11+a12+a22 == 0 ) include_cases = false;
+	      if ( u11+u12+u22 == 0 ) include_controls = false;		
+	    }
+	  
+	  
+	  if (par::qt)
+	    {
+	      
+	      double p;
+	      
+	      if (par::HWD_standard)
+		{
+		  double tot = b11 + b12 + b22;
+		  double exp_11 = freq * freq * tot;
+		  double exp_12 = 2 * freq * (1-freq) * tot;
+		  double exp_22 = (1-freq) * (1-freq) * tot;
+		  
+		  double chisq = ( (b11-exp_11)*(b11-exp_11) ) / exp_11 
+		    + ( (b12-exp_12)*(b12-exp_12) ) / exp_12 
+		    + ( (b22-exp_22)*(b22-exp_22) ) / exp_22 ;
+	      
+		  p = chiprobP(chisq,1);
+		}
+	      else
+		p = SNPHWE( b12, b11, b22 );
+	      
+
+	      if (par::HWD_report)
+		{
+		  HWD << setw(par::pp_maxsnp) << (*loc)->name << " "
+		      << setw(8) << "ALL(QT)" << " "
+		      << setw(20) << (int2str(b11)+
+				      "/"+int2str(b12)+
+				      "/"+int2str(b22)) << " "
+		      << setw(8) << (double)b12/(double)(b11+b12+b22) << " "
+		      << setw(8) << 2 * freq * (1-freq)  << " "
+		      << setw(12) << p << "\n";
+		}
+	      
+	      if ( p <= par::HWD_limit ) 
+		{
+		  cnt++;
+		  *d = true;
+		}
+	    }
+	  else
+	    {
+	      // For case/control data
+
+	      double p, p_a, p_u;
+	      
+	      if (par::HWD_standard)
+		{
+		  double exp_a11 = afreq * afreq * (a11+a12+a22);
+		  double exp_a12 = 2 * afreq * (1-afreq) * (a11+a12+a22);
+		  double exp_a22 = (1-afreq) * (1-afreq) * (a11+a12+a22);
+
+		  double exp_u11 = ufreq * ufreq * (u11+u12+u22);
+		  double exp_u12 = 2 * ufreq * (1-ufreq) * (u11+u12+u22);
+		  double exp_u22 = (1-ufreq) * (1-ufreq) * (u11+u12+u22);
+		  
+		  double exp_11 = freq * freq * (b11+b12+b22);
+		  double exp_12 = 2 * freq * (1-freq) * (b11+b12+b22);
+		  double exp_22 = (1-freq) * (1-freq) * (b11+b12+b22);
+		  
+		  double chisq_a = ( (a11-exp_a11)*(a11-exp_a11) ) / exp_a11 
+		    + ( (a12-exp_a12)*(a12-exp_a12) ) / exp_a12 
+		    + ( (a22-exp_a22)*(a22-exp_a22) ) / exp_a22 ;
+		  
+		  double chisq_u = ( (u11-exp_u11)*(u11-exp_u11) ) / exp_u11 
+		    + ( (u12-exp_u12)*(u12-exp_u12) ) / exp_u12 
+		    + ( (u22-exp_u22)*(u22-exp_u22) ) / exp_u22 ;
+		  
+		  double chisq = ( (b11-exp_11)*(b11-exp_11) ) / exp_11 
+		    + ( (b12-exp_12)*(b12-exp_12) ) / exp_12 
+		    + ( (b22-exp_22)*(b22-exp_22) ) / exp_22 ;
+		  
+		  p = chiprobP(chisq,1);
+		  p_a = chiprobP(chisq_a,1);
+		  p_u = chiprobP(chisq_u,1);
+		}
+	      else
+		{
+		  p = SNPHWE( b12, b11, b22 );
+		  p_a = SNPHWE( a12, a11, a22 );
+		  p_u = SNPHWE( u12, u11, u22 );
+		}
+
+	      if (par::HWD_report)
+		{
+		  
+		  HWD << setw(par::pp_maxsnp) << (*loc)->name  << " "
+		      << setw(8) << "ALL" << " "
+		    
+		      << setw(20) 
+		      << int2str(b11)+"/"+int2str(b12)+"/"+int2str(b22) << " "
+		      << setw(8) << (double)b12/(double)(b11+b12+b22) << " "
+		      << setw(8) << 2 * freq * (1-freq)  << " "
+		      << setw(12) << p  << "\n";
+
+
+		  HWD << setw(par::pp_maxsnp) << (*loc)->name  << " "
+		      << setw(8) << "AFF" << " "
+		      << setw(20) 
+		      << int2str(a11)+"/"+int2str(a12)+"/"+int2str(a22) << " "
+		      << setw(8) << (double)a12/(double)(a11+a12+a22) << " "
+		      << setw(8) << 2 * afreq * (1-afreq)  << " ";
+	
+		  
+		  if (include_cases)
+		    HWD << setw(12) << p_a  << "\n";
+		  else
+		    HWD << setw(12) << "NA" << "\n";
+
+
+		  HWD << setw(par::pp_maxsnp) << (*loc)->name  << " "
+		      << setw(8) << "UNAFF" << " "
+		      << setw(20) 
+		      << int2str(u11)+"/"+int2str(u12)+"/"+int2str(u22) << " "
+		      << setw(8) << (double)u12/(double)(u11+u12+u22) << " "
+		      << setw(8) << 2 * ufreq * (1-ufreq)  << " ";
+
+		    
+		  if (include_controls)
+		    HWD << setw(12) << p_u  << "\n";
+		  else
+		    HWD << setw(12) << "NA" << "\n";		  
+		  		  
+		}
+	      
+	      // Increase counts: in cases
+	      if ( include_cases && p_a < par::HWD_limit && p>-1 ) cnt_a++;
+	      
+	      // Controls (and, if possible, exclude on this value)
+	      if ( include_controls &&
+		   p_u < par::HWD_limit && p>-1 ) 
+		{
+		  cnt_u++;	      
+
+		  if ( ! par::HWD_filter_on_all ) 
+		    { 
+		      *d = true;
+		      cnt++;
+		    }
+		}
+	      
+	      // In total sample, and if needed, exclude here
+	      if ( p < par::HWD_limit && p>-1 ) 
+		{ 
+		  if ( par::HWD_filter_on_all || ! include_controls )
+		    {
+		      *d = true;
+		      cnt++;
+		    }
+		}
+	      
+
+
+
+	    }
+
+
+	  // next locus
+	  ++loc;
+	  ++d;
+	}
+      
+
+      // Finish the report...
+      if (par::HWD_report)
+	HWD.close();
+      
+      // ...or finish pruning
+      
+      printLOG( int2str(cnt) + 
+		" markers to be excluded based on HWE test ( p <= " +
+		dbl2str(par::HWD_limit) + " )\n");
+      
+      if (par::bt)
+	{
+	  printLOG("\t" + int2str(cnt_a) + " markers failed HWE test in cases\n");
+	  printLOG("\t" + int2str(cnt_u) + " markers failed HWE test in controls\n");
+	}
+    }
+  
+  
+
+  
+  ///////////////////////////////////////////////////
+  // Summary statistics for genotyping/missing rates
+
+  if (par::report_missing)
+    {
+      
+
+      ///////////////////////////////////////////
+      // Report by genotyping rate by individual
+      // possibly allowing for obligatory missingness
+      
+      printLOG( "Writing individual missingness information to [ " +
+		par::output_file_name + ".imiss ] \n");
+      
+      ofstream MIS;
+      string f = par::output_file_name + ".imiss";
+      MIS.open(f.c_str(), ifstream::out);
+      MIS << setw(par::pp_maxfid) << "FID" << " "
+	  << setw(par::pp_maxiid) << "IID" << " "
+	  << setw(10) << "MISS_PHENO" << " "
+	  << setw(8) << "N_MISS" << " ";
+      if ( par::oblig_missing ) 
+	MIS << setw(8) << "N_GENO" << " ";
+      MIS << setw(8) << "F_MISS" << "\n";
+      
+      for (int i=0; i<n; i++)
+	{
+	  
+ 	  MIS << setw(par::pp_maxfid) << sample[i]->fid << " " 
+	      << setw(par::pp_maxiid) << sample[i]->iid << " ";
+	  if (sample[i]->missing) MIS << setw(10) << "Y" << " ";
+	  else MIS << setw(10) << "N" << " " ;
+	  
+	  
+	  // Sum missingness over all SNPs
+	  int m=0;       // Missing SNPs
+	  int nsnps=0;   // All non-obligatory missing SNPs
+	  
+	  if ( ! par::oblig_missing )
+	    {
+	      nsnps = locus.size();
+	      for (int l=0; l<nsnps;l++)
+		if ( MISSING(i,l) ) m++;
+	      
+	    }
+	  else // ... allow oblig missing values
+	    {
+	      for (int l=0; l<locus.size();l++)
+		{
+		  if ( ! obligMissing(i,l) )
+		    {
+		      if ( MISSING(i,l) )
+			++m;
+		      ++nsnps;
+		    }
+		}
+	    }
+	  
+	  MIS << setw(8) << m << " ";
+	  if ( par::oblig_missing) 
+	    MIS << setw(8) << nsnps << " ";
+	  MIS << setw(8) << (double)m/(double)nsnps << "\n";
+	  
+	}
+      MIS.close();
+      
+
+
+      ///////////////////////////////////////////
+      // Report by genotyping rate by locus
+      // possibly allowing for sample strata
+      // possibly allowing for obligatory missingness
+
+      printLOG("Writing locus missingness information to [ " +
+	       par::output_file_name +".lmiss ] \n");
+      f = par::output_file_name + ".lmiss";
+      MIS.open(f.c_str(), ifstream::out);
+      MIS.clear();
+      
+      MIS << setw(4) << "CHR" << " " 
+	  << setw(par::pp_maxsnp) << "SNP" << " ";
+	  
+      if (par::include_cluster_from_file)
+	MIS << setw(10) << "CLST" << " ";
+
+      MIS << setw(8) << "N_MISS" << " ";
+      
+      if ( par::oblig_missing )
+	MIS << setw(8) << "N_GENO" << " ";
+      
+      if (par::include_cluster_from_file)
+	MIS << setw(8) << "N_CLST" << " ";
+      
+      MIS << setw(8) << "F_MISS" << "\n";
+      
+      
+      for (int l=0; l<locus.size(); l++)
+	{
+	  
+	  Locus * loc = locus[l];
+	  
+	  // nk==1 for basic missingness (i.e. not stratified by
+	  // cluster)
+	  
+	  for (int k=0; k<nk; k++)
+	    {
+	      
+	      MIS << setw(4) << loc->chr << " "
+		  << setw(par::pp_maxsnp) << loc->name << " ";
+	      
+	      if (par::include_cluster_from_file)
+		MIS << setw(10) << kname[k] << " ";
+	      
+	      int m=0;     // Number of missing genotypes
+	      int c=0;     // Number of people in cluster
+	      int nsnps=0; // Number of actual genotypes in cluster
+	      
+	      for ( int i=0; i<sample.size(); i++)
+		{
+		  if (par::include_cluster_from_file)
+		    {
+		      if ( sample[i]->sol == k ) 
+			{
+			  if ( ( ! par::oblig_missing ) ||
+			       ( ! obligMissing(i,l) ) )
+			    {
+			      if ( MISSING(i,l) ) ++m;
+			      ++nsnps;
+			    }
+			  ++c;
+			}
+		    }
+		  else // ... ignore cluster strata
+		    {
+		      if ( ( ! par::oblig_missing ) ||
+			   ( ! obligMissing(i,l) ) )
+			{
+			  if ( MISSING(i,l) ) ++m;
+			  ++nsnps;
+			}		      
+		    }
+		  
+		  // Next individual
+		}
+	      	      
+	      MIS << setw(8) << m << " ";
+
+	      if (par::include_cluster_from_file)
+		MIS << setw(8) << c << " ";	    
+
+	      if (par::oblig_missing)
+		MIS << setw(8) << nsnps << " ";	    
+
+	      
+	      MIS << setw(8) << (double)m / (double)nsnps << "\n";
+	    }
+	  
+	  // Next SNP
+	}
+      
+      MIS.close();
+
+    }
+  
+
+
+
+  /////////////////////////////////
+  // Remove rare SNPs 
+
+   
+  loc = locus.begin();
+  d = del.begin();
+
+  while ( loc != locus.end() )
+    {
+
+      // Note epsilon correction for MAF, due to floating point 
+      // issues: only apply to the lower MAF range
+
+      if ( (*loc)->freq < 0 || 
+	   (*loc)->freq + par::epsilon < par::min_af ||
+	   (*loc)->freq > par::max_af )        	 
+	{
+	  *d = true;
+	  exc_maf++;
+	}
+
+      d++;
+      loc++;
+    }
+  
+  
+
+  /////////////////////////////////////////
+  // Remove SNPs based on thresholds
+
+  if ( locus.size() > 0 ) 
+    printLOG("Total genotyping rate in remaining individuals is " 
+	     + dbl2str(total_genotyping/(double)locus.size())+"\n");
+  printLOG(int2str(exc_miss)+" SNPs failed missingness test ( GENO > "
+	   +dbl2str(par::MAX_GENO_MISSING)+" )\n");
+  printLOG(int2str(exc_maf)+" SNPs failed frequency test ( MAF < "+dbl2str(par::min_af));
+  if (par::max_af < 0.5 ) printLOG(" or MAF > " + dbl2str(par::max_af));
+  printLOG(" )\n");
+
+
+  int tmp = deleteSNPs(del);
+
+
+  //////////////////////////////////////////
+  // Need to make back to individual major?
+
+  if ( ! original_SNP_major )
+    SNP2Ind();
+
+
+  return;
+
+}
+

Added: trunk/packages/plink/trunk/.pc/gcc43.patch/fisher.cpp
===================================================================
--- trunk/packages/plink/trunk/.pc/gcc43.patch/fisher.cpp	                        (rev 0)
+++ trunk/packages/plink/trunk/.pc/gcc43.patch/fisher.cpp	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,2257 @@
+
+
+//////////////////////////////////////////////////////////////////
+//                                                              //
+//           PLINK (c) 2005-2006 Shaun Purcell                  //
+//                                                              //
+// This file is distributed under the GNU General Public        //
+// License, Version 2.  Please see the file COPYING for more    //
+// details                                                      //
+//                                                              //
+//////////////////////////////////////////////////////////////////
+
+
+#include "fisher.h"
+#include "plink.h"
+#include "helper.h"
+
+double fisher(table_t t)
+{
+
+  int nrow = t.size();
+  if ( nrow == 0 ) 
+    return -9;
+  int ncol = t[0].size();
+  if ( ncol == 0 ) 
+    return -9;
+  double table[200];
+
+  int c=0;
+  
+  for (int j=0; j<ncol; j++)
+    for (int i=0; i<nrow; i++)    
+      {
+	table[c++] = t[i][j];
+      }
+
+  double expect = -1.0;
+  double percnt = 100.0;
+  double emin = 0;
+  double pre = 0, prt = 0;
+  int ws = 300000;
+  
+  fexact(&nrow, &ncol, table, &nrow, &expect, &percnt, &emin, &prt, &pre, &ws);
+
+  return pre;
+  
+//   // Test of routine:
+
+//   double expected = -1.0; 
+//   percnt = 100.0; 
+//   emin = 0.0; 
+//   prt = 0.0; 
+//   double *expectedp = &expected; 
+//   double *percntp = &percnt; 
+//   double *eminp = &emin; 
+//   double *prtp = &prt; 
+//   double pvalue = 0.0; 
+//   double *pvaluep = &pvalue; 
+//   int workspace = 300000; 
+//   int *workspacep = &workspace; 
+  
+//   nrow = 3; 
+//   ncol = 2;     
+//   int *nrowp = &nrow; 
+//   int *ncolp = &ncol;   
+//   double *tmp_table = new double[6]; 
+
+// //   tmp_table[0] =10; 
+// //   tmp_table[1] =20; 
+// //   tmp_table[2] =30; 
+
+// //   tmp_table[3] =40; 
+// //   tmp_table[4] =10; 
+// //   tmp_table[5] =60; 
+
+//   tmp_table[0] =10; 
+//   tmp_table[1] =40; 
+//   tmp_table[2] =20; 
+//   tmp_table[3] =10; 
+//   tmp_table[4] =30; 
+//   tmp_table[5] =60; 
+
+//   fexact(nrowp, ncolp, tmp_table, nrowp, expectedp, percntp,eminp, prtp, pvaluep, workspacep); 
+
+//   cout << "exactP = " << pvalue<<"\n\n"; 
+
+//   exit(0);
+
+//   return pre;
+
+}
+
+
+/*  fisher2.c: this is fexact.c, part of the R 
+    (http://cran.r-project.org) distribution
+    (package ctest).
+    Minor edits by az-Uriarte (rdiaz at cnio.es). May 2003.
+*/
+
+
+/* [Notice from the original fexact.c] 
+   Fisher's exact test for contingency tables -- usage see below
+
+   fexact.f -- translated by f2c (version 19971204).
+   Run through a slightly modified version of MM's f2c-clean.
+   Heavily hand-edited by KH and MM.
+*/
+
+#include <cstdlib>
+#include <cstdio> 
+#include <cmath> 
+
+#include <limits> 
+#define SINT_MAX INT_MAX
+
+#undef min
+#undef max
+#define max(a, b)((a) < (b) ? (b) : (a))
+#define min(a, b)((a) > (b) ? (b) : (a))
+
+static void f2xact(int *nrow, int *ncol, double *table, int *ldtabl,
+		     double *expect, double *percnt, double *emin, double
+		     *prt, double *pre, double *fact, int *ico, int
+		     *iro, int *kyy, int *idif, int *irn, int *key,
+		     int *ldkey, int *ipoin, double *stp, int *ldstp,
+		     int *ifrq, double *dlp, double *dsp, double *tm,
+		     int *key2, int *iwk, double *rwk);
+static void f3xact(int *nrow, int *irow, int *ncol,int *icol,
+		     double *dlp, int *mm, double *fact, int *ico, int
+		     *iro, int *it, int *lb, int *nr, int *nt, int
+		     *nu, int *itc, int *ist, double *stv, double *alen,
+		     const double *tol);
+static void f4xact(int *nrow, int *irow, int *ncol, int *icol,
+		     double *dsp, double *fact, int *icstk, int *ncstk,
+		     int *lstk, int *mstk, int *nstk, int *nrstk, int
+		     *irstk, double *ystk, const double *tol);
+static void f5xact(double *pastp, const double *tol, int *kval, int *key,
+		     int *ldkey, int *ipoin, double *stp, int *ldstp,
+		     int *ifrq, int *npoin, int *nr, int *nl, int
+		     *ifreq, int *itop, int *ipsh);
+static void f6xact(int *nrow, int *irow, int *iflag, int *kyy,
+		      int *key, int *ldkey, int *last, int *ipn);
+static void f7xact(int *nrow, int *imax, int *idif, int *k, int *ks,
+		      int *iflag);
+static void f8xact(int *irow, int *is, int *i1, int *izero, int *knew);
+static double f9xact(int *n, int *mm, int *ir, double *fact);
+static void f10act(int *nrow, int *irow, int *ncol, int *icol,
+		     double *val, int *xmin, double *fact, int *nd,
+		     int *ne, int *m);
+static void f11act(int *irow, int *i1, int *i2, int *knew);
+static void prterr(int icode, char *mes);
+static int iwork(int iwkmax, int *iwkpt, int number, int itype);
+
+#ifdef USING_R
+# define isort(n, ix)R_isort(ix, *n)
+# include <Rmath.h>/* -> pgamma() */
+#else
+ static void isort(int *n, int *ix);
+ static double gammds(double *y, double *p, int *ifault);
+ static double alogam(double *x, int *ifault);
+#endif
+
+/* The only public function : */
+void
+fexact(int *nrow, int *ncol, double *table, int *ldtabl,
+       double *expect, double *percnt, double *emin, double *prt,
+       double *pre, int *workspace)
+{
+
+  /*
+  ALGORITHM 643, COLLECTED ALGORITHMS FROM ACM.
+  THIS WORK PUBLISHED IN TRANSACTIONS ON MATHEMATICAL SOFTWARE,
+  VOL. 19, NO. 4, DECEMBER, 1993, PP. 484-488.
+  -----------------------------------------------------------------------
+  Name:      FEXACT
+  Purpose:    Computes Fisher's exact test probabilities and a hybrid
+        approximation to Fisher exact test probabilities for a
+	      contingency table using the network algorithm.
+  Usage:      CALL FEXACT (NROW, NCOL, TABLE, LDTABL, EXPECT, PERCNT,
+                           EMIN, PRT, PRE)
+  Arguments:
+  NROW    - The number of rows in the table.(Input)
+  NCOL    - The number of columns in the table.(Input)
+  TABLE   - NROW by NCOL matrix containing the contingency
+  table.(Input)
+  LDTABL  - Leading dimension of TABLE exactly as specified
+  in the dimension statement in the calling
+  program.(Input)
+
+  EXPECT  - Expected value used in the hybrid algorithm for
+  deciding when to use asymptotic theory
+  probabilities.(Input)
+  If EXPECT <= 0.0 then asymptotic theory probabilities
+  are not used and Fisher exact test probabilities are
+  computed. Otherwise, if PERCNT or more of the cells in
+  the remaining table have estimated expected values of
+  EXPECT or more, with no remaining cell having expected
+  value less than EMIN, then asymptotic chi-squared
+  probabilities are used.  See the algorithm section of the
+  manual document for details.
+  Use EXPECT = 5.0 to obtain the 'Cochran' condition.
+
+  PERCNT  - Percentage of remaining cells that must have
+  estimated expected values greater than EXPECT
+  before asymptotic probabilities can be used.(Input)
+  See argument EXPECT for details.
+  Use PERCNT = 80.0 to obtain the 'Cochran' condition.
+
+  EMIN    - Minimum cell estimated expected value allowed for
+  asymptotic chi-squared probabilities to be used.(Input)
+  See argument EXPECT for details.
+  Use EMIN = 1.0 to obtain the 'Cochran' condition.
+
+  PRT     - Probability of the observed table for fixed
+  marginal totals.(Output)
+  
+  PRE     - Table p-value.(Output)
+  PRE is the probability of a more extreme table,
+  where `extreme' is in a probabilistic sense.
+  If EXPECT < 0 then the Fisher exact probability
+  is returned.  Otherwise, an approximation to the
+  Fisher exact probability is computed based upon
+  asymptotic chi-squared probabilities for ``large''
+  table expected values.  The user defines ``large''
+  through the arguments EXPECT, PERCNT, and EMIN.
+  
+  Remarks:
+  1. For many problems one megabyte or more of workspace can be
+  required.If the environment supports it, the user should begin
+  by increasing the workspace used to 200,000 units.
+  2. In FEXACT, LDSTP = 30*LDKEY.  The proportion of table space used
+  by STP may be changed by changing the line MULT = 30 below to
+  another value.
+  3. FEXACT may be converted to single precision by setting IREAL = 3,
+     and converting all DOUBLE PRECISION specifications (except the
+     specifications for RWRK, IWRK, and DWRK) to REAL.This will
+     require changing the names and specifications of the intrinsic
+     functions ALOG, AMAX1, AMIN1, EXP, and REAL.  In addition, the
+     machine specific constants will need to be changed, and the name
+     DWRK will need to be changed to RWRK in the call to F2XACT.
+  4. Machine specific constants are specified and documented in F2XACT.
+     A missing value code is specified in both FEXACT and F2XACT.
+  5. Although not a restriction, is is not generally practical to call
+     this routine with large tables which are not sparse and in
+     which the 'hybrid' algorithm has little effect.  For example,
+     although it is feasible to compute exact probabilities for the
+     table
+     1 8 5 4 4 2 2
+     5 3 3 4 3 1 0
+     10 1 4 0 0 0 0,
+     computing exact probabilities for a similar table which has been
+     enlarged by the addition of an extra row (or column) may not be
+     feasible.
+  -----------------------------------------------------------------------
+  */
+
+  /* CONSTANT Parameters : */
+
+  /* To increase the length of the table of paste path lengths relative
+       to the length of the hash table, increase MULT.
+  */
+    const int mult = 30;
+    /* AMISS is a missing value indicator which is returned when the
+       probability is not defined.
+    */
+    const double amiss = -12345.;
+    /*
+      Set IREAL = 4 for DOUBLE PRECISION
+      Set IREAL = 3 for SINGLE PRECISION
+    */
+#define i_real 4
+#define i_int  2
+
+    /* System generated locals */
+    int ikh;
+    /* Local variables */
+    int nco, nro, ntot, numb, iiwk, irwk;
+    int i, j, k, kk, ldkey, ldstp, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10;
+    int i3a, i3b, i3c, i9a, iwkmax, iwkpt;
+
+    /* Workspace Allocation (freed at end) */
+    double *equiv;
+    iwkmax = 2 * (int) (*workspace / 2);
+    //    equiv = (double *) R_alloc(iwkmax / 2, sizeof(double));
+    equiv = (double *) calloc(iwkmax / 2, sizeof(double));
+
+    /* The check could never happen with Calloc!
+    equiv = Calloc(iwkmax / 2, double);
+    if (!equiv) {
+    prterr(0, "Can not allocate specified workspace");
+    } */
+
+#define dwrk (equiv)
+#define iwrk ((int *)equiv)
+#define rwrk ((float *)equiv)
+
+    /* Parameter adjustments */
+    table -= *ldtabl + 1;
+
+    /* Function Body */
+    iwkpt = 0;
+
+    if (*nrow > *ldtabl)
+      prterr(1, "NROW must be less than or equal to LDTABL.");
+
+    ntot = 0;
+    for (i = 1; i <= *nrow; ++i) {
+      for (j = 1; j <= *ncol; ++j) {
+	if (table[i + j * *ldtabl] < 0.)
+	  prterr(2, "All elements of TABLE must be positive.");
+	ntot = (int) (ntot + table[i + j * *ldtabl]);
+      }
+    }
+    if (ntot == 0) {
+      prterr(3, "All elements of TABLE are zero.\n"
+	     "PRT and PRE are set to missing values.");
+      *prt = amiss;
+      *pre = amiss;
+      goto L_End;
+    }
+    
+    nco = max(*nrow, *ncol);
+    nro = *nrow + *ncol - nco;/* = min(*nrow, *ncol) */
+    k = *nrow + *ncol + 1;
+    kk = k * nco;
+    
+    ikh = ntot + 1;
+    i1  = iwork(iwkmax, &iwkpt, ikh, i_real);
+    i2  = iwork(iwkmax, &iwkpt, nco, i_int);
+    i3  = iwork(iwkmax, &iwkpt, nco, i_int);
+    i3a = iwork(iwkmax, &iwkpt, nco, i_int);
+    i3b = iwork(iwkmax, &iwkpt, nro, i_int);
+    i3c = iwork(iwkmax, &iwkpt, nro, i_int);
+    ikh = max(k * 5 + (kk << 1), nco * 7 + 800);
+    iiwk= iwork(iwkmax, &iwkpt, ikh, i_int);
+    ikh = max(nco + 401, k);
+    irwk= iwork(iwkmax, &iwkpt, ikh, i_real);
+
+    /* NOTE:
+       What follows below splits the remaining amount iwkmax - iwkpt of
+       (int) workspace into hash tables as follows.
+       type  size       index
+       INT   2 * ldkey  i4 i5 i11
+       REAL  2 * ldkey  i8 i9 i10
+       REAL  2 * ldstp  i6
+       INT   6 * ldstp  i7
+       Hence, we need ldkey times
+       3 * 2 + 3 * 2 * s + 2 * mult * s + 6 * mult
+       chunks of integer memory, where s = sizeof(REAL) / sizeof(INT).
+       If doubles are used and are twice as long as ints, this gives
+       18 + 10 * mult
+       so that the value of ldkey can be obtained by dividing available
+       (int) workspace by this number.
+       
+       In fact, because iwork() can actually s * n + s - 1 int chunks
+       when allocating a REAL, we use ldkey = available / numb - 1.
+       
+       FIXME:
+       Can we always assume that sizeof(double) / sizeof(int) is 2?
+    */
+    
+    if (i_real == 4) {/* Double precision reals */
+      numb = 18 + 10 * mult;
+    } else {/* Single precision reals */
+      numb = (mult << 3) + 12;
+    }
+    ldkey = (iwkmax - iwkpt) / numb - 1;
+    ldstp = mult * ldkey;
+    ikh = ldkey << 1;i4  = iwork(iwkmax, &iwkpt, ikh, i_int);
+    ikh = ldkey << 1;i5  = iwork(iwkmax, &iwkpt, ikh, i_int);
+    ikh = ldstp << 1;i6  = iwork(iwkmax, &iwkpt, ikh, i_real);
+    ikh = ldstp * 6;i7  = iwork(iwkmax, &iwkpt, ikh, i_int);
+    ikh = ldkey << 1;i8  = iwork(iwkmax, &iwkpt, ikh, i_real);
+    ikh = ldkey << 1;i9  = iwork(iwkmax, &iwkpt, ikh, i_real);
+    ikh = ldkey << 1;i9a = iwork(iwkmax, &iwkpt, ikh, i_real);
+    ikh = ldkey << 1;i10 = iwork(iwkmax, &iwkpt, ikh, i_int);
+
+    /* To convert to double precision, change RWRK to DWRK in the next CALL.
+     */
+    f2xact(nrow,
+	   ncol,
+	   &table[*ldtabl + 1],
+	   ldtabl,
+	   expect,
+	   percnt,
+	   emin,
+	   prt,
+	   pre,
+	   dwrk + i1,
+	   iwrk + i2,
+	   iwrk + i3,
+	   iwrk + i3a,
+	   iwrk + i3b,
+	   iwrk + i3c,
+	   iwrk + i4,
+	   &ldkey,
+	   iwrk + i5,
+	   dwrk + i6,
+	   &ldstp,
+	   iwrk + i7,
+	   dwrk + i8,
+	   dwrk + i9,
+	   dwrk + i9a,
+	   iwrk + i10,
+	   iwrk + iiwk,
+	   dwrk + irwk);
+    
+L_End:
+    /* Free(equiv); */
+    free(equiv);
+    return;
+}
+
+#undef rwrk
+#undef iwrk
+#undef dwrk
+
+
+/*
+  -----------------------------------------------------------------------
+  Name:F2XACT
+  Purpose:Computes Fisher's exact test for a contingency table,
+  routine with workspace variables specified.
+  Usage:F2XACT (NROW, NCOL, TABLE, LDTABL, EXPECT, PERCNT,
+  EMIN, PRT, PRE, FACT, ICO, IRO, KYY, IDIF,
+  IRN, KEY, LDKEY, IPOIN, STP, LDSTP, IFRQ,
+  DLP, DSP, TM, KEY2, IWK, RWK)
+  -----------------------------------------------------------------------
+*/
+void
+f2xact(int *nrow, int *ncol, double *table, int *ldtabl,
+       double *expect, double *percnt, double *emin, double *prt,
+       double *pre, double *fact, int *ico, int *iro, int *kyy,
+       int *idif, int *irn, int *key, int *ldkey, int *ipoin,
+       double *stp, int *ldstp, int *ifrq, double *dlp, double *dsp,
+       double *tm, int *key2, int *iwk, double *rwk)
+{
+  /* IMAX is the largest representable int on the machine. */
+  const int imax = SINT_MAX;
+  
+  /* AMISS is a missing value indicator which is returned when the
+     probability is not defined. */
+  const double amiss = -12345.;
+  
+  /* TOL is chosen as the square root of the smallest relative spacing. */
+#ifndef Macintosh
+  const  static double tol = 3.45254e-7;
+#else
+  static double tol = 3.45254e-7;
+#endif    
+  /* EMX is a large positive value used in comparing expected values. */
+  const static double emx = 1e30;
+  
+  /* Local variables {{any really need to be static ???}} */
+  static int kval, kmax, jkey, last, ipsh, itmp, itop, jstp, ntot,
+    jstp2, jstp3, jstp4, i, ii, j, k, n, iflag, ncell, ifreq, chisq,
+    ikkey, ikstp, ikstp2, k1, kb, kd, ks,
+    i31, i32, i33, i34, i35, i36, i37, i38, i39,
+    i41, i42, i43, i44, i45, i46, i47, i48, i310, i311,
+    nco, nrb, ipn, ipo, itp, nro, nro2;
+  static double dspt, dd, df,ddf, drn,dro, emn, obs, obs2, obs3,
+    pastp, pv, tmp;
+  double d1;
+#ifndef USING_R
+  double d2;
+  static int ifault;
+#endif
+  bool nr_gt_nc;
+  
+    /* Parameter adjustments */
+  table -= *ldtabl + 1;
+  --ico;
+  --iro;
+  --kyy;
+  --idif;
+  --irn;
+  --key;
+  --ipoin;
+  --stp;
+  --ifrq;
+  --dlp;
+  --dsp;
+  --tm;
+  --key2;
+  --iwk;
+  --rwk;
+  
+
+  /* Check table dimensions */
+  if (*nrow > *ldtabl)
+    prterr(1, "NROW must be less than or equal to LDTABL.");
+  if (*ncol <= 1)
+    prterr(4, "NCOL must be at least 2");
+
+    /* Initialize KEY array */
+    for (i = 1; i <= *ldkey << 1; ++i) {
+      key[i] = -9999;
+      key2[i] = -9999;
+    }
+    /* Initialize parameters */
+    *pre = 0.;
+    itop = 0;
+    if (*expect > 0.)
+      emn = *emin;
+    else
+      emn = emx;
+
+    nr_gt_nc =  *nrow > *ncol;
+    /* nco := max(nrow, ncol) : */
+    if(nr_gt_nc)
+      nco = *nrow;
+    else
+      nco = *ncol;
+    /* Initialize pointers for workspace */
+    /* f3xact */
+    i31 = 1;
+    i32 = i31 + nco;
+    i33 = i32 + nco;
+    i34 = i33 + nco;
+    i35 = i34 + nco;
+    i36 = i35 + nco;
+    i37 = i36 + nco;
+    i38 = i37 + nco;
+    i39 = i38 + 400;
+    i310 = 1;
+    i311 = 401;
+    /* f4xact */
+    k = *nrow + *ncol + 1;
+    i41 = 1;
+    i42 = i41 + k;
+    i43 = i42 + k;
+    i44 = i43 + k;
+    i45 = i44 + k;
+    i46 = i45 + k;
+    i47 = i46 + k * nco;
+    i48 = 1;
+
+    /* Compute row marginals and total */
+    ntot = 0;
+    for (i = 1; i <= *nrow; ++i) {
+      iro[i] = 0;
+      for (j = 1; j <= *ncol; ++j) {
+	    if (table[i + j * *ldtabl] < -1e-4)
+	      prterr(2, "All elements of TABLE must be positive.");
+	        iro[i] += (int) table[i + j * *ldtabl];
+		}
+      ntot += iro[i];
+    }
+
+    if (ntot == 0) {
+      prterr(3, "All elements of TABLE are zero.\n"
+	            "PRT and PRE are set to missing values.");
+      *pre = *prt = amiss;
+      return;
+    }
+
+    /* Column marginals */
+    for (i = 1; i <= *ncol; ++i) {
+      ico[i] = 0;
+      for (j = 1; j <= *nrow; ++j)
+	    ico[i] += (int) table[j + i * *ldtabl];
+    }
+
+    /* sort marginals */
+    isort(nrow, &iro[1]);
+    isort(ncol, &ico[1]);
+
+    /*Determine row and column marginals.
+      Define max(nrow,ncol) =: nco >= nro := min(nrow,ncol)
+      nco is defined above
+
+      Swap marginals if necessary toico[1:nco] & iro[1:nro]
+    */
+    if (nr_gt_nc) {
+      nro = *ncol;
+      /* Swap marginals */
+      for (i = 1; i <= nco; ++i) {
+	    itmp = iro[i];
+	        if (i <= nro)
+		  iro[i] = ico[i];
+		    ico[i] = itmp;
+		    }
+    } else
+      nro = *nrow;
+
+
+    /* Get multiplers for stack */
+    kyy[1] = 1;
+    for (i = 2; i <= nro; ++i) {
+      /* Hash table multipliers */
+      if (iro[i - 1] + 1 <= imax / kyy[i - 1]) {
+	    kyy[i] = kyy[i - 1] * (iro[i - 1] + 1);
+	        j /= kyy[i - 1];
+		} else
+		      goto L_ERR_5;
+    }
+    /* Maximum product */
+    if (iro[nro - 1] + 1 <= imax / kyy[nro - 1]) {
+      kmax = (iro[nro] + 1) * kyy[nro - 1];
+    } else {
+    L_ERR_5:
+      prterr(5, "The hash table key cannot be computed because "
+	            "the largest key\n"
+	            "is larger than the largest representable int.\n"
+	            "The algorithm cannot proceed.\n"
+	            "Reduce the workspace size, or use `exact = FALSE'.");
+      return;
+    }
+
+    /* Compute log factorials */
+    fact[0] = 0.;
+    fact[1] = 0.;
+    if(ntot >= 2) fact[2] = log(2.); 
+    /* MM: old code assuming log() to be SLOW */
+    for (i = 3; i <= ntot; i += 2) {
+      fact[i] = fact[i - 1] + log((double) i);
+      j = i + 1;
+      if (j <= ntot)
+	    fact[j] = fact[i] + fact[2] + fact[j / 2] - fact[j / 2 - 1];
+    }
+    /* Compute obs := observed path length */
+    obs = tol;
+    ntot = 0;
+    for (j = 1; j <= nco; ++j) {
+      dd = 0.;
+      for (i = 1; i <= nro; ++i) {
+	    if (nr_gt_nc) {
+	      dd += fact[(int) table[j + i * *ldtabl]];
+	      ntot +=    (int) table[j + i * *ldtabl];
+	          } else {
+		    dd += fact[(int) table[i + j * *ldtabl]];
+		    ntot +=    (int) table[i + j * *ldtabl];
+		        }
+	    }
+      obs += fact[ico[j]] - dd;
+    }
+    /* Denominator of observed table: DRO */
+    dro = f9xact(&nro, &ntot, &iro[1], fact);
+    *prt = exp(obs - dro);
+    /* Initialize pointers */
+    k = nco;
+    last = *ldkey + 1;
+    jkey = *ldkey + 1;
+    jstp = *ldstp + 1;
+    jstp2 = *ldstp * 3 + 1;
+    jstp3 = (*ldstp << 2) + 1;
+    jstp4 = *ldstp * 5 + 1;
+    ikkey = 0;
+    ikstp = 0;
+    ikstp2 = *ldstp << 1;
+    ipo = 1;
+    ipoin[1] = 1;
+    stp[1] = 0.;
+    ifrq[1] = 1;
+    ifrq[ikstp2 + 1] = -1;
+
+Outer_Loop:
+    kb = nco - k + 1;
+    ks = 0;
+    n = ico[kb];
+    kd = nro + 1;
+    kmax = nro;
+    /* IDIF is the difference in going to the daughter */
+    for (i = 1; i <= nro; ++i)
+      idif[i] = 0;
+
+    /* Generate the first daughter */
+    do {
+      --kd;
+      ntot = min(n, iro[kd]);
+      idif[kd] = ntot;
+      if (idif[kmax] == 0)
+	    --kmax;
+      n -= ntot;
+    }
+    while (n > 0 && kd != 1);
+
+    if (n != 0) {
+      goto L310;
+    }
+
+    k1 = k - 1;
+    n = ico[kb];
+    ntot = 0;
+    for (i = kb + 1; i <= nco; ++i)
+      ntot += ico[i];
+
+
+L150:
+    /* Arc to daughter length=ICO(KB) */
+    for (i = 1; i <= nro; ++i)
+      irn[i] = iro[i] - idif[i];
+
+    /* Sort irn */
+    if (k1 > 1) {
+      if (nro == 2) {
+	    if (irn[1] > irn[2]) {
+	      ii = irn[1];
+	      irn[1] = irn[2];
+	      irn[2] = ii;
+	          }
+	    } else if (nro == 3) {
+	          ii = irn[1];
+		      if (ii > irn[3]) {
+			if (ii > irn[2]) {
+			      if (irn[2] > irn[3]) {
+				irn[1] = irn[3];
+				irn[3] = ii;
+				    } else {
+				      irn[1] = irn[2];
+				      irn[2] = irn[3];
+				      irn[3] = ii;
+				          }
+			      } else {
+				    irn[1] = irn[3];
+				        irn[3] = irn[2];
+					    irn[2] = ii;
+					    }
+			    } else if (ii > irn[2]) {
+			      irn[1] = irn[2];
+			      irn[2] = ii;
+			          } else if (irn[2] > irn[3]) {
+				    ii = irn[2];
+				    irn[2] = irn[3];
+				    irn[3] = ii;
+				        }
+		      } else {
+			    for (j = 2; j <= nro; ++j) {
+			      i = j - 1;
+			      ii = irn[j];
+
+			      while (ii < irn[i]) {
+				    irn[i + 1] = irn[i];
+				        --i;
+					    if (i == 0)
+					      break;
+					    }
+			      irn[i + 1] = ii;
+			          }
+			    }
+      /* Adjust start for zero */
+      for (i = 1; i <= nro; ++i) {
+	    if (irn[i] != 0)
+	      break;
+	    }
+
+      nrb = i;
+      nro2 = nro - i + 1;
+    } else {
+      nrb = 1;
+      nro2 = nro;
+    }
+    /* Some table values */
+    ddf = f9xact(&nro, &n, &idif[1], fact);
+    drn = f9xact(&nro2, &ntot, &irn[nrb], fact) - dro + ddf;
+    /* Get hash value */
+    if (k1 > 1) {
+      kval = irn[1] + irn[2] * kyy[2];
+      for (i = 3; i <= nro; ++i) {
+	    kval += irn[i] * kyy[i];
+	    }
+      /* Get hash table entry */
+      i = kval % (*ldkey << 1) + 1;
+      /* Search for unused location */
+      for (itp = i; itp <= *ldkey << 1; ++itp) {
+	    ii = key2[itp];
+	        if (ii == kval) {
+		  goto L240;
+		      } else if (ii < 0) {
+			key2[itp] = kval;
+			dlp[itp] = 1.;
+			dsp[itp] = 1.;
+			goto L240;
+			    }
+		}
+
+      for (itp = 1; itp <= i - 1; ++itp) {
+	    ii = key2[itp];
+	        if (ii == kval) {
+		  goto L240;
+		      } else if (ii < 0) {
+			key2[itp] = kval;
+			dlp[itp] = 1.;
+			goto L240;
+			    }
+		}
+
+      /* KH
+	    prterr(6, "LDKEY is too small.\n"
+	       "It is not possible to give the value of LDKEY required,\n"
+	          "but you could try doubling LDKEY (and possibly LDSTP).");
+      */
+      prterr(6, "LDKEY is too small for this problem.\n"
+	            "Try increasing the size of the workspace.");
+    }
+
+L240:
+    ipsh = (1);
+    /* Recover pastp */
+    ipn = ipoin[ipo + ikkey];
+    pastp = stp[ipn + ikstp];
+    ifreq = ifrq[ipn + ikstp];
+    /* Compute shortest and longest path */
+    if (k1 > 1) {
+      obs2 = obs - fact[ico[kb + 1]] - fact[ico[kb + 2]] - ddf;
+      for (i = 3; i <= k1; ++i) {
+	    obs2 -= fact[ico[kb + i]];
+	    }
+      if (dlp[itp] > 0.) {
+	    dspt = obs - obs2 - ddf;
+	    /* Compute longest path */
+	        dlp[itp] = 0.;
+		    f3xact(&nro2, &irn[nrb], &k1, &ico[kb + 1], &dlp[itp],
+			      &ntot, fact, &iwk[i31], &iwk[i32], &iwk[i33],
+			      &iwk[i34], &iwk[i35], &iwk[i36], &iwk[i37],
+			      &iwk[i38], &iwk[i39], &rwk[i310], &rwk[i311], &tol);
+		        dlp[itp] = min(0., dlp[itp]);
+			/* Compute shortest path */
+			    dsp[itp] = dspt;
+			        f4xact(&nro2, &irn[nrb], &k1, &ico[kb + 1], &dsp[itp], fact,
+				          &iwk[i47], &iwk[i41], &iwk[i42], &iwk[i43],
+				          &iwk[i44], &iwk[i45], &iwk[i46], &rwk[i48], &tol);
+				    dsp[itp] = min(0., dsp[itp] - dspt);
+				    /* Use chi-squared approximation? */
+				        if ((irn[nrb] * ico[kb + 1]) > ntot * emn) {
+					  ncell = 0;
+					  for (i = 0; i < nro2; ++i)
+					        for (j = 1; j <= k1; ++j)
+						  if (irn[nrb + i] * ico[kb + j] >= ntot * *expect)
+						        ncell++;
+
+					  if (ncell * 100 >= k1 * nro2 * *percnt) {
+					        tmp = 0.;
+						    for (i = 0; i < nro2; ++i)
+						      tmp += (fact[irn[nrb + i]] -
+							      fact[irn[nrb + i] - 1]);
+						        tmp *= k1 - 1;
+							    for (j = 1; j <= k1; ++j)
+							      tmp += (nro2 - 1) * (fact[ico[kb + j]] -
+										        fact[ico[kb + j] - 1]);
+							        df = (double) ((nro2 - 1) * (k1 - 1));
+								    tmp += df * 1.83787706640934548356065947281;
+								        tmp -= (nro2 * k1 - 1) * (fact[ntot] - fact[ntot - 1]);
+									    tm[itp] = (obs - dro) * -2. - tmp;
+									    } else {
+									      /* tm(itp) set to a flag value */
+									          tm[itp] = -9876.;
+										  }
+					      } else {
+						tm[itp] = -9876.;
+						    }
+					}
+      obs3 = obs2 - dlp[itp];
+      obs2 -= dsp[itp];
+      if (tm[itp] == -9876.) {
+	    chisq = (0);
+	    } else {
+	          chisq = (1);
+		      tmp = tm[itp];
+		      }
+    } else {
+      obs2 = obs - drn - dro;
+      obs3 = obs2;
+    }
+
+L300:
+    /* Process node with new PASTP */
+    if (pastp <= obs3) {
+      /* Update pre */
+      *pre += (double) ifreq * exp(pastp + drn);
+    } else if (pastp < obs2) {
+      if (chisq) {
+	    df = (double) ((nro2 - 1) * (k1 - 1));
+#ifdef USING_R
+	        pv = pgamma(fmax2(0., tmp + (pastp + drn) * 2.) / 2.,
+			    df / 2., /*scale = */ 1.,
+			    /*lower_tail = */FALSE, /*log_p = */ FALSE);
+#else
+		    d1 = max(0., tmp + (pastp + drn) * 2.) / 2.;
+		        d2 = df / 2.;
+			    pv = 1. - gammds(&d1, &d2, &ifault);
+#endif
+			        *pre += (double) ifreq * exp(pastp + drn) * pv;
+				} else {
+				  /* Put daughter on queue */
+				      d1 = pastp + ddf;
+				          f5xact(&d1, &tol, &kval, &key[jkey], ldkey, &ipoin[jkey],
+						    &stp[jstp], ldstp, &ifrq[jstp], &ifrq[jstp2],
+						    &ifrq[jstp3], &ifrq[jstp4], &ifreq, &itop, &ipsh);
+					      ipsh = (0);
+					      }
+    }
+    /* Get next PASTP on chain */
+    ipn = ifrq[ipn + ikstp2];
+    if (ipn > 0) {
+      pastp = stp[ipn + ikstp];
+      ifreq = ifrq[ipn + ikstp];
+      goto L300;
+    }
+    /* Generate a new daughter node */
+    f7xact(&kmax, &iro[1], &idif[1], &kd, &ks, &iflag);
+    if (iflag != 1) {
+      goto L150;
+    }
+
+L310:
+    /* Go get a new mother from stage K */
+    do {
+      iflag = 1;
+      f6xact(&nro, &iro[1], &iflag, &kyy[1], &key[ikkey + 1], ldkey,
+	            &last, &ipo);
+      /* Update pointers */
+      if (iflag != 3)
+	    goto Outer_Loop;
+      /* else  iflag == 3 : no additional nodes to process */
+      --k;
+      itop = 0;
+      ikkey = jkey - 1;
+      ikstp = jstp - 1;
+      ikstp2 = jstp2 - 1;
+      jkey = *ldkey - jkey + 2;
+      jstp = *ldstp - jstp + 2;
+      jstp2 = (*ldstp << 1) + jstp;
+      for (i = 1; i <= *ldkey << 1; ++i)
+	    key2[i] = -9999;
+
+    } while (k >= 2);
+}
+
+/*
+  -----------------------------------------------------------------------
+  Name:      F3XACT
+  Purpose:    Computes the shortest path length for a given table.
+  Usage:      F3XACT (NROW, IROW, NCOL, ICOL, DLP, MM, FACT, ICO, IRO,
+        IT, LB, NR, NT, NU, ITC, IST, STV, ALEN, TOL)
+  Arguments:
+  NROW    - The number of rows in the table.(Input)
+    IROW    - Vector of length NROW containing the row sums
+    for the table.(Input)
+    NCOL    - The number of columns in the table.(Input)
+    ICOL    - Vector of length K containing the column sums
+    for the table.(Input)
+    DLP     - The longest path for the table.(Output)
+    MM    - The total count in the table.(Output)
+    FACT    - Vector containing the logarithms of factorials.(Input)
+    ICO     - Work vector of length MAX(NROW,NCOL).
+    IRO     - Work vector of length MAX(NROW,NCOL).
+    IT    - Work vector of length MAX(NROW,NCOL).
+    LB    - Work vector of length MAX(NROW,NCOL).
+    NR    - Work vector of length MAX(NROW,NCOL).
+    NT    - Work vector of length MAX(NROW,NCOL).
+    NU    - Work vector of length MAX(NROW,NCOL).
+    ITC     - Work vector of length 400.
+    IST     - Work vector of length 400.
+    STV     - Work vector of length 400.
+    ALEN    - Work vector of length MAX(NROW,NCOL).
+    TOL     - Tolerance.(Input)
+  -----------------------------------------------------------------------
+*/
+
+void
+f3xact(int *nrow, int *irow, int *ncol, int *icol, double *dlp,
+       int *mm, double *fact, int *ico, int *iro, int *it,
+       int *lb, int *nr, int *nt, int *nu, int *itc, int *ist,
+       double *stv, double *alen, const double *tol)
+{
+  /* Initialized data */
+    static int ldst = 200;
+    static int nst = 0;
+    static int nitc = 0;
+
+    /* Local variables */
+    static int xmin;
+    static int i, k;
+    static double v;
+    static int n11, n12, ii, nn, ks, ic1, ic2, nc1, nn1;
+    static int nr1, nco;
+    static double val;
+    static int nct, ipn, irl, key, lev, itp, nro;
+    static double vmn;
+    static int nrt, kyy, nc1s;
+
+    /* Parameter adjustments */
+    --stv;
+    --ist;
+    --itc;
+    --nu;
+    --nt;
+    --nr;
+    --lb;
+    --it;
+    --iro;
+    --ico;
+    --icol;
+    --irow;
+
+    /* Function Body */
+    for (i = 0; i <= *ncol; ++i) {
+      alen[i] = 0.;
+    }
+    for (i = 1; i <= 400; ++i) {
+      ist[i] = -1;
+    }
+    /* nrow is 1 */
+    if (*nrow <= 1) {
+      if (*nrow > 0) {
+	    *dlp -= fact[icol[1]];
+	        for (i = 2; i <= *ncol; ++i) {
+		  *dlp -= fact[icol[i]];
+		      }
+		}
+      return;
+    }
+    /* ncol is 1 */
+    if (*ncol <= 1) {
+      if (*ncol > 0) {
+	    *dlp = *dlp - fact[irow[1]] - fact[irow[2]];
+	        for (i = 3; i <= *nrow; ++i) {
+		  *dlp -= fact[irow[i]];
+		      }
+		}
+      return;
+    }
+    /* 2 by 2 table */
+    if (*nrow * *ncol == 4) {
+      n11 = (irow[1] + 1) * (icol[1] + 1) / (*mm + 2);
+      n12 = irow[1] - n11;
+      *dlp = *dlp - fact[n11] - fact[n12] - fact[icol[1] - n11]
+	    - fact[icol[2] - n12];
+      return;
+    }
+    /* Test for optimal table */
+    val = 0.;
+    xmin = (0);
+    if (irow[*nrow] <= irow[1] + *ncol) {
+      f10act(nrow, &irow[1], ncol, &icol[1], &val, &xmin, fact,
+	            &lb[1], &nu[1], &nr[1]);
+    }
+    if (! xmin) {
+      if (icol[*ncol] <= icol[1] + *nrow) {
+	    f10act(ncol, &icol[1], nrow, &irow[1], &val, &xmin, fact,
+		      &lb[1], &nu[1], &nr[1]);
+	    }
+    }
+
+    if (xmin) {
+      *dlp -= val;
+      return;
+    }
+    /* Setup for dynamic programming */
+    nn = *mm;
+    /* Minimize ncol */
+    if (*nrow >= *ncol) {
+      nro = *nrow;
+      nco = *ncol;
+      for (i = 1; i <= *nrow; ++i) {
+	    iro[i] = irow[i];
+	    }
+      ico[1] = icol[1];
+      nt[1] = nn - ico[1];
+      for (i = 2; i <= *ncol; ++i) {
+	    ico[i] = icol[i];
+	        nt[i] = nt[i - 1] - ico[i];
+		}
+    } else {
+      nro = *ncol;
+      nco = *nrow;
+      ico[1] = irow[1];
+      nt[1] = nn - ico[1];
+      for (i = 2; i <= *nrow; ++i) {
+	    ico[i] = irow[i];
+	        nt[i] = nt[i - 1] - ico[i];
+		}
+      for (i = 1; i <= *ncol; ++i)
+	    iro[i] = icol[i];
+    }
+    /* Initialize pointers */
+    vmn = 1e10;
+    nc1s = nco - 1;
+    irl = 1;
+    ks = 0;
+    k = ldst;
+    kyy = ico[nco] + 1;
+
+ LnewNode: /* Setup to generate new node */
+
+    lev = 1;
+    nr1 = nro - 1;
+    nrt = iro[irl];
+    nct = ico[1];
+    lb[1] = (int) ((double) ((nrt + 1) * (nct + 1)) /
+		       (double) (nn + nr1 * nc1s + 1) - *tol) - 1;
+    nu[1] = (int) ((double) ((nrt + nc1s) * (nct + nr1)) /
+		       (double) (nn + nr1 + nc1s)) - lb[1] + 1;
+    nr[1] = nrt - lb[1];
+
+ LoopNode: /* Generate a node */
+    --nu[lev];
+    if (nu[lev] == 0) {
+      if (lev == 1)
+	    goto L200;
+
+      --lev;
+      goto LoopNode;
+    }
+    ++lb[lev];
+    --nr[lev];
+L120:
+    alen[lev] = alen[lev - 1] + fact[lb[lev]];
+    if (lev < nc1s) {
+      nn1 = nt[lev];
+      nrt = nr[lev];
+      ++lev;
+      nc1 = nco - lev;
+      nct = ico[lev];
+      lb[lev] = (int) ((double) ((nrt + 1) * (nct + 1)) /
+		         (double) (nn1 + nr1 * nc1 + 1) - *tol);
+      nu[lev] = (int) ((double) ((nrt + nc1) * (nct + nr1)) /
+		         (double) (nn1 + nr1 + nc1) - lb[lev] + 1);
+      nr[lev] = nrt - lb[lev];
+      goto L120;
+    }
+    alen[nco] = alen[lev] + fact[nr[lev]];
+    lb[nco] = nr[lev];
+
+    v = val + alen[nco];
+    if (nro == 2) {
+      /* Only 1 row left */
+      v = v + fact[ico[1] - lb[1]] + fact[ico[2] - lb[2]];
+      for (i = 3; i <= nco; ++i) {
+	    v += fact[ico[i] - lb[i]];
+	    }
+      if (v < vmn) {
+	    vmn = v;
+	    }
+    } else if (nro == 3 && nco == 2) {
+      /* 3 rows and 2 columns */
+      nn1 = nn - iro[irl] + 2;
+      ic1 = ico[1] - lb[1];
+      ic2 = ico[2] - lb[2];
+      n11 = (iro[irl + 1] + 1) * (ic1 + 1) / nn1;
+      n12 = iro[irl + 1] - n11;
+      v = v + fact[n11] + fact[n12] + fact[ic1 - n11]
+	    + fact[ic2 - n12];
+      if (v < vmn) {
+	    vmn = v;
+	    }
+    } else {
+      /* Column marginals are new node */
+      for (i = 1; i <= nco; ++i) {
+	    it[i] = ico[i] - lb[i];
+	    }
+      /* Sort column marginals */
+      if (nco == 2) {
+	    if (it[1] > it[2]) {
+	      ii = it[1];
+	      it[1] = it[2];
+	      it[2] = ii;
+	          }
+	    } else if (nco == 3) {
+	          ii = it[1];
+		      if (ii > it[3]) {
+			if (ii > it[2]) {
+			      if (it[2] > it[3]) {
+				it[1] = it[3];
+				it[3] = ii;
+				    } else {
+				      it[1] = it[2];
+				      it[2] = it[3];
+				      it[3] = ii;
+				          }
+			      } else {
+				    it[1] = it[3];
+				        it[3] = it[2];
+					    it[2] = ii;
+					    }
+			    } else if (ii > it[2]) {
+			      it[1] = it[2];
+			      it[2] = ii;
+			          } else if (it[2] > it[3]) {
+				    ii = it[2];
+				    it[2] = it[3];
+				    it[3] = ii;
+				        }
+		      } else {
+			    isort(&nco, &it[1]);
+			    }
+      /* Compute hash value */
+      key = it[1] * kyy + it[2];
+      for (i = 3; i <= nco; ++i) {
+	    key = it[i] + key * kyy;
+	    }
+      if(key < 0)
+	error("Bug in FEXACT: gave negative key \n");
+      
+      /* Table index */
+      ipn = key % ldst + 1;
+
+      /* Find empty position */
+      for (itp = ipn, ii = ks + ipn; itp <= ldst; ++itp, ++ii) {
+	    if (ist[ii] < 0) {
+	      goto L180;
+	          } else if (ist[ii] == key) {
+		    goto L190;
+		        }
+	    }
+
+      for (itp = 1, ii = ks + 1; itp <= ipn - 1; ++itp, ++ii) {
+	    if (ist[ii] < 0) {
+	      goto L180;
+	          } else if (ist[ii] == key) {
+		    goto L190;
+		        }
+	    }
+
+      error("Stack length exceeded in f3xact");
+	
+    L180: /* Push onto stack */
+      ist[ii] = key;
+      stv[ii] = v;
+      ++nst;
+      ii = nst + ks;
+      itc[ii] = itp;
+      goto LoopNode;
+
+    L190: /* Marginals already on stack */
+      stv[ii] = min(v, stv[ii]);
+    }
+    goto LoopNode;
+
+
+ L200: /* Pop item from stack */
+    if (nitc > 0) {
+      /* Stack index */
+      itp = itc[nitc + k] + k;
+      --nitc;
+      val = stv[itp];
+      key = ist[itp];
+      ist[itp] = -1;
+      /* Compute marginals */
+      for (i = nco; i >= 2; --i) {
+	    ico[i] = key % kyy;
+	        key /= kyy;
+		}
+      ico[1] = key;
+      /* Set up nt array */
+      nt[1] = nn - ico[1];
+      for (i = 2; i <= nco; ++i)
+	    nt[i] = nt[i - 1] - ico[i];
+
+      /* Test for optimality (L90) */
+      xmin = (0);
+      if (iro[nro] <= iro[irl] + nco) {
+	    f10act(&nro, &iro[irl], &nco, &ico[1], &val, &xmin, fact,
+		      &lb[1], &nu[1], &nr[1]);
+	    }
+      if (!xmin && ico[nco] <= ico[1] + nro)
+	    f10act(&nco, &ico[1], &nro, &iro[irl], &val, &xmin, fact,
+		      &lb[1], &nu[1], &nr[1]);
+      if (xmin) {
+	    if (vmn > val)
+	      vmn = val;
+	        goto L200;
+		}
+      else goto LnewNode;
+
+    } else if (nro > 2 && nst > 0) {
+      /* Go to next level */
+      nitc = nst;
+      nst = 0;
+      k = ks;
+      ks = ldst - ks;
+      nn -= iro[irl];
+      ++irl;
+      --nro;
+      goto L200;
+    }
+
+    *dlp -= vmn;
+}
+
+/*
+  -----------------------------------------------------------------------
+  Name:      F4XACT
+  Purpose:    Computes the longest path length for a given table.
+  Usage:      CALL F4XACT (NROW, IROW, NCOL, ICOL, DSP, FACT, ICSTK,
+    NCSTK, LSTK, MSTK, NSTK, NRSTK, IRSTK, YSTK,
+      TOL)
+  Arguments:
+  NROW   - The number of rows in the table.(Input)
+     IROW   - Vector of length NROW containing the row sums for the
+           table.  (Input)
+     NCOL   - The number of columns in the table.  (Input)
+     ICOL   - Vector of length K containing the column sums for the
+           table.  (Input)
+	   DSP    - The shortest path for the table.(Output)
+     FACT   - Vector containing the logarithms of factorials.  (Input)
+     ICSTK  - NCOL by NROW+NCOL+1 work array.
+     NCSTK  - Work vector of length NROW+NCOL+1.
+     LSTK   - Work vector of length NROW+NCOL+1.
+     MSTK   - Work vector of length NROW+NCOL+1.
+     NSTK   - Work vector of length NROW+NCOL+1.
+     NRSTK  - Work vector of length NROW+NCOL+1.
+     IRSTK  - NROW by MAX(NROW,NCOL) work array.
+     YSTK   - Work vector of length NROW+NCOL+1.
+     TOL    - Tolerance.  (Input)
+  -----------------------------------------------------------------------
+*/
+
+void
+f4xact(int *nrow, int *irow, int *ncol, int *icol, double *dsp,
+       double *fact, int *icstk, int *ncstk, int *lstk, int *mstk,
+       int *nstk, int *nrstk, int *irstk, double *ystk, const double *tol)
+{
+  /* System generated locals */
+    int ikh;
+
+    /* Local variables */
+    int i, j, k, l, m, n, mn, ic1, ir1, ict, irt, istk, nco, nro;
+    double y, amx;
+
+    /* Parameter adjustments */
+    irstk -= *nrow + 1;
+    --irow;
+    icstk -= *ncol + 1;
+    --icol;
+    --ncstk;
+    --lstk;
+    --mstk;
+    --nstk;
+    --nrstk;
+    --ystk;
+
+    /* Function Body */
+    /* Take care of the easy cases first */
+    if (*nrow == 1) {
+      for (i = 1; i <= *ncol; ++i) {
+	    *dsp -= fact[icol[i]];
+	    }
+      return;
+    }
+    if (*ncol == 1) {
+      for (i = 1; i <= *nrow; ++i) {
+	    *dsp -= fact[irow[i]];
+	    }
+      return;
+    }
+    if (*nrow * *ncol == 4) {
+      if (irow[2] <= icol[2]) {
+	    *dsp = *dsp - fact[irow[2]] - fact[icol[1]]
+	      - fact[icol[2] - irow[2]];
+	    } else {
+	          *dsp = *dsp - fact[icol[2]] - fact[irow[1]]
+		    - fact[irow[2] - icol[2]];
+		  }
+      return;
+    }
+    /* initialization before loop */
+    for (i = 1; i <= *nrow; ++i) {
+      irstk[i + *nrow] = irow[*nrow - i + 1];
+    }
+    for (j = 1; j <= *ncol; ++j) {
+      icstk[j + *ncol] = icol[*ncol - j + 1];
+    }
+
+    nro = *nrow;
+    nco = *ncol;
+    nrstk[1] = nro;
+    ncstk[1] = nco;
+    ystk[1] = 0.;
+    y = 0.;
+    istk = 1;
+    l = 1;
+    amx = 0.;
+
+    /* First LOOP */
+    do {
+      ir1 = irstk[istk * *nrow + 1];
+      ic1 = icstk[istk * *ncol + 1];
+      if (ir1 > ic1) {
+	    if (nro >= nco) {
+	      m = nco - 1;n = 2;
+	          } else {
+		    m = nro;n = 1;
+		        }
+	    } else if (ir1 < ic1) {
+	          if (nro <= nco) {
+		    m = nro - 1;n = 1;
+		        } else {
+			  m = nco;n = 2;
+			      }
+		  } else {
+		        if (nro <= nco) {
+			  m = nro - 1;n = 1;
+			      } else {
+				m = nco - 1;n = 2;
+				    }
+			}
+
+    L60:
+      if (n == 1) {
+	    i = l; j = 1;
+	    } else {
+	          i = 1; j = l;
+		  }
+
+      irt = irstk[i + istk * *nrow];
+      ict = icstk[j + istk * *ncol];
+      mn = irt;
+      if (mn > ict) {
+	    mn = ict;
+	    }
+      y += fact[mn];
+      if (irt == ict) {
+	    --nro;
+	        --nco;
+		    f11act(&irstk[istk * *nrow + 1], &i, &nro,
+			      &irstk[(istk + 1) * *nrow + 1]);
+		        f11act(&icstk[istk * *ncol + 1], &j, &nco,
+			          &icstk[(istk + 1) * *ncol + 1]);
+			} else if (irt > ict) {
+			      --nco;
+			          f11act(&icstk[istk * *ncol + 1], &j, &nco,
+					    &icstk[(istk + 1) * *ncol + 1]);
+				      ikh = irt - ict;
+				          f8xact(&irstk[istk * *nrow + 1], &ikh, &i,
+						    &nro, &irstk[(istk + 1) * *nrow + 1]);
+					  } else {
+					        --nro;
+						    f11act(&irstk[istk * *nrow + 1], &i, &nro,
+							      &irstk[(istk + 1) * *nrow + 1]);
+						        ikh = ict - irt;
+							    f8xact(&icstk[istk * *ncol + 1], &ikh, &j,
+								      &nco, &icstk[(istk + 1) * *ncol + 1]);
+							    }
+
+      if (nro == 1) {
+	    for (k = 1; k <= nco; ++k) {
+	      y += fact[icstk[k + (istk + 1) * *ncol]];
+	          }
+	        break;
+		}
+      if (nco == 1) {
+	    for (k = 1; k <= nro; ++k) {
+	      y += fact[irstk[k + (istk + 1) * *nrow]];
+	          }
+	        break;
+		}
+
+      lstk[istk] = l;
+      mstk[istk] = m;
+      nstk[istk] = n;
+      ++istk;
+      nrstk[istk] = nro;
+      ncstk[istk] = nco;
+      ystk[istk] = y;
+      l = 1;
+    } while(1);/* end do */
+
+    /* L90:*/
+    if (y > amx) {
+      amx = y;
+      if (*dsp - amx <= *tol) {
+	    *dsp = 0.;
+	        return;
+		}
+    }
+
+L100:
+    --istk;
+    if (istk == 0) {
+      *dsp -= amx;
+      if (*dsp - amx <= *tol) {
+	    *dsp = 0.;
+	    }
+      return;
+    }
+    l = lstk[istk] + 1;
+
+    /* L110: */
+    for(;; ++l) {
+      if (l > mstk[istk])goto L100;
+
+      n = nstk[istk];
+      nro = nrstk[istk];
+      nco = ncstk[istk];
+      y = ystk[istk];
+      if (n == 1) {
+	if (irstk[l    + istk * *nrow] <
+	    irstk[l - 1 + istk * *nrow])goto L60;
+	}
+      else if (n == 2) {
+	if (icstk[l    + istk * *ncol] <
+	    icstk[l - 1 + istk * *ncol])goto L60;
+	}
+    }
+}
+
+/*
+  -----------------------------------------------------------------------
+  Name:      F5XACT
+  Purpose:    Put node on stack in network algorithm.
+  Usage:      CALL F5XACT (PASTP, TOL, KVAL, KEY, LDKEY, IPOIN, STP,
+    LDSTP, IFRQ, NPOIN, NR, NL, IFREQ, ITOP,
+      IPSH)
+  Arguments:
+  PASTP  - The past path length.(Input)
+  TOL    - Tolerance for equivalence of past path lengths.  (Input)
+  KVAL   - Key value.  (Input)
+  KEY    - Vector of length LDKEY containing the key values.(in/out)
+  LDKEY  - Length of vector KEY.  (Input)
+     IPOIN  - Vector of length LDKEY pointing to the
+     linked list of past path lengths.  (in/out)
+     STP    - Vector of length LSDTP containing the
+     linked lists of past path lengths.  (in/out)
+     LDSTP  - Length of vector STP.  (Input)
+     IFRQ   - Vector of length LDSTP containing the past path
+     frequencies.  (in/out)
+     NPOIN  - Vector of length LDSTP containing the pointers to
+     the next past path length.  (in/out)
+     NR    - Vector of length LDSTP containing the right object
+           pointers in the tree of past path lengths.        (in/out)
+	   NL    - Vector of length LDSTP containing the left object
+	         pointers in the tree of past path lengths.        (in/out)
+     IFREQ  - Frequency of the current path length.             (Input)
+     ITOP   - Pointer to the top of STP.  (Input)
+     IPSH   - Option parameter. (Input)
+           If IPSH is true, the past path length is found in the
+	         table KEY.  Otherwise the location of the past path
+		       length is assumed known and to have been found in
+		             a previous call. ==>>>>> USING "static" variables
+  -----------------------------------------------------------------------
+*/
+
+void
+f5xact(double *pastp, const double *tol, int *kval, int *key, int *ldkey,
+       int *ipoin, double *stp, int *ldstp, int *ifrq, int *npoin,
+       int *nr, int *nl, int *ifreq, int *itop, int *ipsh)
+{
+  /* Local variables */
+    static int itmp, ird, ipn, itp;
+    double test1, test2;
+
+    /* Parameter adjustments */
+    --nl;
+    --nr;
+    --npoin;
+    --ifrq;
+    --stp;
+    --ipoin;
+    --key;
+
+    /* Function Body */
+    if (*ipsh) {
+      /* Convert KVAL to int in range 1, ..., LDKEY. */
+      ird = *kval % *ldkey + 1;
+      /* Search for an unused location */
+      for (itp = ird; itp <= *ldkey; ++itp) {
+	    if (key[itp] == *kval) {
+	      goto L40;
+	          }
+	        if (key[itp] < 0) {
+		  goto L30;
+		      }
+		}
+      for (itp = 1; itp <= ird - 1; ++itp) {
+	    if (key[itp] == *kval) {
+	      goto L40;
+	          }
+	        if (key[itp] < 0) {
+		  goto L30;
+		      }
+		}
+      /* Return if KEY array is full */
+      /* KH
+	   prterr(6, "LDKEY is too small for this problem.\n"
+	     "It is not possible to estimate the value of LDKEY "
+	       "required,\n"
+	         "but twice the current value may be sufficient.");
+      */
+      prterr(6, "LDKEY is too small for this problem.\n"
+	            "Try increasing the size of the workspace.");
+
+      /* Update KEY */
+L30:
+      key[itp] = *kval;
+      ++(*itop);
+      ipoin[itp] = *itop;
+      /* Return if STP array full */
+      if (*itop > *ldstp) {
+	/* KH
+	          prterr(7, "LDSTP is too small for this problem.\n"
+		         "It is not possible to estimate the value of LDSTP "
+			        "required,\n"
+				       "but twice the current value may be sufficient.");
+	*/
+	    prterr(7, "LDSTP is too small for this problem.\n"
+		      "Try increasing the size of the workspace.");
+	    }
+      /* Update STP, etc. */
+      npoin[*itop] = -1;
+      nr[*itop] = -1;
+      nl[*itop] = -1;
+      stp[*itop] = *pastp;
+      ifrq[*itop] = *ifreq;
+      return;
+    }
+
+    /* Find location, if any, of pastp */
+L40:
+    ipn = ipoin[itp];
+    test1 = *pastp - *tol;
+    test2 = *pastp + *tol;
+
+L50:
+    if (stp[ipn] < test1) {
+      ipn = nl[ipn];
+      if (ipn > 0) {
+	    goto L50;
+	    }
+    } else if (stp[ipn] > test2) {
+      ipn = nr[ipn];
+      if (ipn > 0) {
+	    goto L50;
+	    }
+    } else {
+      ifrq[ipn] += *ifreq;
+      return;
+    }
+    /* Return if STP array full */
+    ++(*itop);
+    if (*itop > *ldstp) {
+      /*
+	  prterr(7, "LDSTP is too small for this problem.\n"
+	    "It is not possible to estimate the value of LDSTP "
+	      "required,\n"
+	        "but twice the current value may be sufficient.");
+      */
+      prterr(7, "LDSTP is too small for this problem.\n"
+	            "Try increasing the size of the workspace.");
+      return;
+    }
+    /* Find location to add value */
+    ipn = ipoin[itp];
+    itmp = ipn;
+
+L60:
+    if (stp[ipn] < test1) {
+      itmp = ipn;
+      ipn = nl[ipn];
+      if (ipn > 0) {
+	    goto L60;
+	    } else {
+	          nl[itmp] = *itop;
+		  }
+    } else if (stp[ipn] > test2) {
+      itmp = ipn;
+      ipn = nr[ipn];
+      if (ipn > 0) {
+	    goto L60;
+	    } else {
+	          nr[itmp] = *itop;
+		  }
+    }
+    /* Update STP, etc. */
+    npoin[*itop] = npoin[itmp];
+    npoin[itmp] = *itop;
+    stp[*itop] = *pastp;
+    ifrq[*itop] = *ifreq;
+    nl[*itop] = -1;
+    nr[*itop] = -1;
+}
+
+/*
+  -----------------------------------------------------------------------
+  Name:      F6XACT
+  Purpose:    Pop a node off the stack.
+  Usage:      CALL F6XACT (NROW, IROW, IFLAG, KYY, KEY, LDKEY, LAST, IPN)
+  Arguments:
+  NROW    - The number of rows in the table.(Input)
+    IROW    - Vector of length nrow containing the row sums on
+    output.(Output)
+    IFLAG   - Set to 3 if there are no additional nodes to process.
+    (Output)
+    KYY     - Constant mutlipliers used in forming the hash
+    table key.(Input)
+    KEY     - Vector of length LDKEY containing the hash table
+    keys.(In/out)
+    LDKEY   - Length of vector KEY.(Input)
+    LAST    - Index of the last key popped off the stack.(In/out)
+    IPN     - Pointer to the linked list of past path lengths.(Output)
+  -----------------------------------------------------------------------
+*/
+void
+f6xact(int *nrow, int *irow, int *iflag, int *kyy, int *key, int
+       *ldkey, int *last, int *ipn)
+{
+    int kval, j;
+
+    /* Parameter adjustments */
+    --key;
+    --kyy;
+    --irow;
+
+    /* Function Body */
+L10:
+    ++(*last);
+    if (*last <= *ldkey) {
+      if (key[*last] < 0) {
+	    goto L10;
+	    }
+      /* Get KVAL from the stack */
+      kval = key[*last];
+      key[*last] = -9999;
+      for (j = *nrow; j >= 2; --j) {
+	    irow[j] = kval / kyy[j];
+	        kval -= irow[j] * kyy[j];
+		}
+      irow[1] = kval;
+      *ipn = *last;
+    } else {
+      *last = 0;
+      *iflag = 3;
+    }
+    return;
+}
+
+/*
+  -----------------------------------------------------------------------
+  Name:      F7XACT
+  Purpose:    Generate the new nodes for given marinal totals.
+  Usage:      CALL F7XACT (NROW, IMAX, IDIF, K, KS, IFLAG)
+  Arguments:
+  NROW    - The number of rows in the table.(Input)
+  IMAX    - The row marginal totals.(Input)
+  IDIF    - The column counts for the new column.(in/out)
+  K    - Indicator for the row to decrement.(in/out)
+  KS    - Indicator for the row to increment.(in/out)
+  IFLAG   - Status indicator.(Output)
+        If IFLAG is zero, a new table was generated.  For
+	      IFLAG = 1, no additional tables could be generated.
+  -----------------------------------------------------------------------
+*/
+
+void
+f7xact(int *nrow, int *imax, int *idif, int *k, int *ks,
+       int *iflag)
+    
+{
+    int i, m, k1, mm;
+
+    /* Parameter adjustments */
+    --idif;
+    --imax;
+
+    /* Function Body */
+    *iflag = 0;
+    /* Find node which can be incremented, ks */
+    if (*ks == 0)
+      do {
+	    ++(*ks);
+	    } while (idif[*ks] == imax[*ks]);
+
+    /* Find node to decrement (>ks) */
+    if (idif[*k] > 0 && *k > *ks) {
+      --idif[*k];
+      do {
+	    --(*k);
+	    } while(imax[*k] == 0);
+
+      m = *k;
+
+      /* Find node to increment (>=ks) */
+      while (idif[m] >= imax[m]) {
+	    --m;
+	    }
+      ++idif[m];
+      /* Change ks */
+      if (m == *ks) {
+	    if (idif[m] == imax[m]) {
+	      *ks = *k;
+	          }
+	    }
+    }
+    else {
+ Loop:
+      /* Check for finish */
+      for (k1 = *k + 1; k1 <= *nrow; ++k1) {
+	    if (idif[k1] > 0) {
+	      goto L70;
+	          }
+	    }
+      *iflag = 1;
+      return;
+
+ L70:
+      /* Reallocate counts */
+      mm = 1;
+      for (i = 1; i <= *k; ++i) {
+	    mm += idif[i];
+	        idif[i] = 0;
+		}
+      *k = k1;
+
+      do {
+	    --(*k);
+	        m = min(mm, imax[*k]);
+		    idif[*k] = m;
+		        mm -= m;
+			} while (mm > 0 && *k != 1);
+
+      /* Check that all counts reallocated */
+      if (mm > 0) {
+	    if (k1 != *nrow) {
+	      *k = k1;
+	      goto Loop;
+	          }
+	        *iflag = 1;
+		    return;
+		    }
+      /* Get ks */
+      --idif[k1];
+      *ks = 0;
+      do {
+	    ++(*ks);
+	        if (*ks > *k) {
+		  return;
+		      }
+		} while (idif[*ks] >= imax[*ks]);
+    }
+}
+
+/*
+  -----------------------------------------------------------------------
+  Name:      F8XACT
+  Purpose:    Routine for reducing a vector when there is a zero
+        element.
+  Usage:      CALL F8XACT (IROW, IS, I1, IZERO, NEW)
+  Arguments:
+  IROW   - Vector containing the row counts.(Input)
+  IS    - Indicator.(Input)
+  I1    - Indicator.(Input)
+  IZERO  - Position of the zero.(Input)
+  NEW    - Vector of new row counts.(Output)
+  -----------------------------------------------------------------------
+*/
+
+void
+f8xact(int *irow, int *is, int *i1, int *izero, int *knew)
+{
+    int i;
+
+    /* Parameter adjustments */
+    --knew;
+    --irow;
+
+    /* Function Body */
+    for (i = 1; i < *i1; ++i)
+      knew[i] = irow[i];
+
+    for (i = *i1; i <= *izero - 1; ++i) {
+      if (*is >= irow[i + 1])
+	    break;
+      knew[i] = irow[i + 1];
+    }
+
+    knew[i] = *is;
+
+    for(;;) {
+      ++i;
+      if (i > *izero)
+	    return;
+      knew[i] = irow[i];
+    }
+}
+
+/*
+  -----------------------------------------------------------------------
+  Name:      F9XACT
+  Purpose:    Computes the log of a multinomial coefficient.
+  Usage:      F9XACT(N, MM, IR, FACT)
+  Arguments:
+  N    - Length of IR.(Input)
+  MM    - Number for factorial in numerator.(Input)
+  IR    - Vector of length N containing the numbers for
+  the denominator of the factorial.(Input)
+  FACT   - Table of log factorials.(Input)
+  F9XACT - The log of the multinomal coefficient.(Output)
+  -----------------------------------------------------------------------
+*/
+
+double
+f9xact(int *n, int *mm, int *ir, double *fact)
+{
+    double d;
+    int k;
+
+    d = fact[*mm];
+    for (k = 0; k < *n; k++)
+      d -= fact[ir[k]];
+    return d;
+}
+
+/*
+  -----------------------------------------------------------------------
+  Name:    F10ACT
+  Purpose:  Computes the shortest path length for special tables.
+  Usage:    F10ACT (NROW, IROW, NCOL, ICOL, VAL, XMIN, FACT, ND, NE, M)
+  Arguments:
+  NROW   - The number of rows in the table.(Input)
+  IROW   - Vector of length NROW containing the row totals.(Input)
+  NCOL   - The number of columns in the table.  (Input)
+     ICO    - Vector of length NCOL containing the column totals.(Input)
+     VAL    - The shortest path.  (Output)
+     XMIN   - Set to true if shortest path obtained.  (Output)
+     FACT   - Vector containing the logarithms of factorials.   (Input)
+     ND    - Workspace vector of length NROW.(Input)
+     NE    - Workspace vector of length NCOL.(Input)
+     M    - Workspace vector of length NCOL.(Input)
+
+  Chapter:    STAT/LIBRARY Categorical and Discrete Data Analysis
+  -----------------------------------------------------------------------
+*/
+
+void
+f10act(int *nrow, int *irow, int *ncol, int *icol, double *val,
+       int *xmin, double *fact, int *nd, int *ne, int *m)
+{
+  /* Local variables */
+    int i, is, ix, nrw1;
+
+    /* Parameter adjustments */
+    --m;
+    --ne;
+    --nd;
+    --icol;
+    --irow;
+
+    /* Function Body */
+    for (i = 1; i <= *nrow - 1; ++i)
+      nd[i] = 0;
+
+    is = icol[1] / *nrow;
+    ix = icol[1] - *nrow * is;
+    ne[1] = is;
+    m[1] = ix;
+    if (ix != 0)
+      ++nd[ix];
+
+    for (i = 2; i <= *ncol; ++i) {
+      ix = icol[i] / *nrow;
+      ne[i] = ix;
+      is += ix;
+      ix = icol[i] - *nrow * ix;
+      m[i] = ix;
+      if (ix != 0)
+	    ++nd[ix];
+    }
+
+    for (i = *nrow - 2; i >= 1; --i)
+      nd[i] += nd[i + 1];
+
+    ix = 0;
+    nrw1 = *nrow + 1;
+    for (i = *nrow; i >= 2; --i) {
+      ix = ix + is + nd[nrw1 - i] - irow[i];
+      if (ix < 0)
+	    return;
+    }
+
+    for (i = 1; i <= *ncol; ++i) {
+      ix = ne[i];
+      is = m[i];
+      *val = *val + is * fact[ix + 1] + (*nrow - is) * fact[ix];
+    }
+    *xmin = (1);
+
+    return;
+}
+
+/*
+  -----------------------------------------------------------------------
+  Name:      F11ACT
+  Purpose:    Routine for revising row totals.
+  Usage:      CALL F11ACT (IROW, I1, I2, KNEW)
+  Arguments:
+  IROW   - Vector containing the row totals.(Input)
+  I1    - Indicator.(Input)
+  I2    - Indicator.  (Input)
+  KNEW    - Vector containing the row totals.(Output)
+  -----------------------------------------------------------------------
+*/
+void
+f11act(int *irow, int *i1, int *i2, int *knew)
+{
+    int i;
+
+    /* Parameter adjustments */
+    --knew;
+    --irow;
+
+    for (i = 1; i <= (*i1 - 1); ++i)knew[i] = irow[i];
+    for (i = *i1; i <= *i2; ++i)knew[i] = irow[i + 1];
+
+    return;
+}
+
+void prterr(int icode, char *mes)
+{ error("FEXACT error "+int2str(icode)); }
+
+/*
+  -----------------------------------------------------------------------
+  Name:      iwork
+  Purpose:    Routine for allocating workspace.
+  Usage:      iwork (iwkmax, iwkpt, number, itype)
+  Arguments:
+  iwkmax - Maximum (int) amount of workspace.(Input)
+  iwkpt  - Amount of (int) workspace currently allocated.(in/out)
+  number - Number of elements of workspace desired.(Input)
+  itype  - Workspace type.(Input)
+        ITYPE  TYPE
+	2    integer
+	3    float
+	4    double
+     iwork(): Index in rwrk, dwrk, or iwrk of the beginning of
+     the first free element in the workspace array.(Output)
+  -----------------------------------------------------------------------
+*/
+int
+iwork(int iwkmax, int *iwkpt, int number, int itype)
+{
+    int i;
+
+    i = *iwkpt;
+    if (itype == 2 || itype == 3)
+      *iwkpt += number;
+    else { /* double */
+      if (i % 2 != 0)
+	    ++i;
+      *iwkpt += (number << 1);
+      i /= 2;
+    }
+    if (*iwkpt > iwkmax)
+      prterr(40, "Out of workspace.");
+
+    return i;
+}
+
+#ifndef USING_R
+
+void isort(int *n, int *ix)
+{
+  /*
+  -----------------------------------------------------------------------
+  Name:      ISORT
+  Purpose:    Shell sort for an int vector.
+  Usage:      CALL ISORT (N, IX)
+  Arguments:
+  N    - Lenth of vector IX.(Input)
+  IX    - Vector to be sorted.(in/out)
+  -----------------------------------------------------------------------
+  */
+    static int ikey, i, j, m, il[10], kl, it, iu[10], ku;
+
+    /* Parameter adjustments */
+    --ix;
+
+    /* Function Body */
+    m = 1;
+    i = 1;
+    j = *n;
+
+L10:
+    if (i >= j) {
+      goto L40;
+    }
+    kl = i;
+    ku = j;
+    ikey = i;
+    ++j;
+    /* Find element in first half */
+L20:
+    ++i;
+    if (i < j) {
+      if (ix[ikey] > ix[i]) {
+	    goto L20;
+	    }
+    }
+    /* Find element in second half */
+L30:
+    --j;
+    if (ix[j] > ix[ikey]) {
+      goto L30;
+    }
+    /* Interchange */
+    if (i < j) {
+      it = ix[i];
+      ix[i] = ix[j];
+      ix[j] = it;
+      goto L20;
+    }
+    it = ix[ikey];
+    ix[ikey] = ix[j];
+    ix[j] = it;
+    /* Save upper and lower subscripts of the array yet to be sorted */
+    if (m < 11) {
+      if (j - kl < ku - j) {
+	    il[m - 1] = j + 1;
+	        iu[m - 1] = ku;
+		    i = kl;
+		        --j;
+			} else {
+			      il[m - 1] = kl;
+			          iu[m - 1] = j - 1;
+				      i = j + 1;
+				          j = ku;
+					  }
+      ++m;
+      goto L10;
+    } else {
+      prterr(20, "This should never occur.");
+    }
+    /* Use another segment */
+L40:
+    --m;
+    if (m == 0) {
+      return;
+    }
+    i = il[m - 1];
+    j = iu[m - 1];
+    goto L10;
+}
+
+double gammds(double *y, double *p, int *ifault)
+{
+  /*
+  -----------------------------------------------------------------------
+  Name:      GAMMDS
+  Purpose:    Cumulative distribution for the gamma distribution.
+  Usage:      PGAMMA (Q, ALPHA,IFAULT)
+  Arguments:
+  Q    - Value at which the distribution is desired.  (Input)
+     ALPHA  - Parameter in the gamma distribution.  (Input)
+     IFAULT - Error indicator.(Output)
+            IFAULT  DEFINITION
+	     0     No error
+	      1     An argument is misspecified.
+	       2     A numerical error has occurred.
+     PGAMMA - The cdf for the gamma distribution with parameter alpha
+           evaluated at Q.  (Output)
+  -----------------------------------------------------------------------
+
+  Algorithm AS 147 APPL. Statist. (1980) VOL. 29, P. 113
+
+  Computes the incomplete gamma integral for positive parameters Y, P
+  using and infinite series.
+  */
+
+    static double a, c, f, g;
+    static int ifail;
+
+    /* Checks for the admissibility of arguments and value of F */
+    *ifault = 1;
+    g = 0.;
+    if (*y <= 0. || *p <= 0.) {
+      return g;
+    }
+    *ifault = 2;
+
+    /*
+      ALOGAM is natural log of gamma function no need to test ifail as
+      an error is impossible
+    */
+
+    a = *p + 1.;
+    f = exp(*p * log(*y) - alogam(&a, &ifail) - *y);
+    if (f == 0.) {
+      return g;
+    }
+    *ifault = 0;
+
+    /* Series begins */
+    c = 1.;
+    g = 1.;
+    a = *p;
+L10:
+    a += 1.;
+    c = c * *y / a;
+    g += c;
+    if (c / g > 1e-6) {
+      goto L10;
+    }
+    g *= f;
+    return g;
+}
+
+/*
+  -----------------------------------------------------------------------
+  Name:      ALOGAM
+  Purpose:    Value of the log-gamma function.
+  Usage:      ALOGAM (X, IFAULT)
+  Arguments:
+  X    - Value at which the log-gamma function is to be evaluated.
+        (Input)
+	IFAULT  - Error indicator. (Output)
+	       IFAULT  DEFINITION
+	        0     No error
+		 1     X < 0
+     ALGAMA - The value of the log-gamma function at XX.  (Output)
+  -----------------------------------------------------------------------
+
+  Algorithm ACM 291, Comm. ACM. (1966) Vol. 9, P. 684
+
+  Evaluates natural logarithm of gamma(x) for X greater than zero.
+*/
+
+double alogam(double *x, int *ifault)
+{
+  /* Initialized data */
+
+    static double a1 = .918938533204673;
+    static double a2 = 5.95238095238e-4;
+    static double a3 = 7.93650793651e-4;
+    static double a4 = .002777777777778;
+    static double a5 = .083333333333333;
+
+    /* Local variables */
+    static double f, y, z;
+
+    *ifault = 1;
+    if (*x < 0.) {
+      return(0.);
+    }
+    *ifault = 0;
+    y = *x;
+    f = 0.;
+    if (y >= 7.) {
+      goto L30;
+    }
+    f = y;
+L10:
+    y += 1.;
+    if (y >= 7.) {
+      goto L20;
+    }
+    f *= y;
+    goto L10;
+L20:
+    f = -log(f);
+L30:
+    z = 1. / (y * y);
+    return(f + (y - .5) * log(y) - y + a1 +
+	      (((-a2 * z + a3) * z - a4) * z + a5) / y);
+}
+
+#endif /* not USING_R */
+

Added: trunk/packages/plink/trunk/.pc/gcc43.patch/nlist.cpp
===================================================================
--- trunk/packages/plink/trunk/.pc/gcc43.patch/nlist.cpp	                        (rev 0)
+++ trunk/packages/plink/trunk/.pc/gcc43.patch/nlist.cpp	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,258 @@
+
+
+//////////////////////////////////////////////////////////////////
+//                                                              //
+//           PLINK (c) 2005-2007 Shaun Purcell                  //
+//                                                              //
+// This file is distributed under the GNU General Public        //
+// License, Version 2.  Please see the file COPYING for more    //
+// details                                                      //
+//                                                              //
+//////////////////////////////////////////////////////////////////
+
+#include <string>
+#include <vector>
+
+#include "nlist.h"
+
+vector<int> NList::deparseNumberList(string input)
+{
+
+  // We have a string that should contain integers, possibily
+  // separated by "," and "-" characters
+
+  // Use 1-N coding up until the last moment, instead of 
+  // standard 0..N-1 coding
+
+  firstWord = "1";
+  lastWord = int2str(maxcat);
+
+  vector<string> tok = tokenize(input);
+  vector<int> nums;
+  for (int i=0; i<tok.size(); i++)
+    {
+      int j;
+      if ( tok[i] == range_string )
+	nums.push_back(-1);
+      else
+	{
+	  if ( ! from_string<int>( j, tok[i] , std::dec))
+	    continue;
+	  nums.push_back(j);
+	}
+    }
+  return expandNumberList(nums);
+}
+
+
+vector<int> NList::deparseStringList(string input, map<string,int> * mapping)
+{
+  
+  // Assume map contains a 0..N-1 coding in the map
+  
+  map<string,int>::iterator im = mapping->begin();
+  while ( im != mapping->end() )
+    {
+      int i = im->second;
+      
+      if ( i == 0 )
+	firstWord = im->first;
+      
+      if ( i == maxcat - 1 ) 
+	lastWord = im->first;
+
+      ++im;
+    }
+
+
+  ////////////////////////////////////////////////////////////////
+  // Convert string codes to numbers, then call deparseNumberList
+  
+  // But incrememnt to 1..N coding here, i.e. so that it is 
+  // similar process to the human-friendly 1..N coding for a
+  // numeric list
+
+  vector<string> tok = tokenize(input);
+  vector<int> nums;
+  for (int i=0; i<tok.size(); i++)
+    {
+      map<string,int>::iterator im = mapping->find(tok[i]);
+      if ( im != mapping->end() )
+	nums.push_back(im->second + 1);
+      else if ( tok[i] == range_string )
+	nums.push_back(-1);
+      else 
+	error("Cannot find value: " + tok[i] + "\n");
+    }
+  return expandNumberList(nums);  
+}
+
+
+
+vector<int> NList::expandNumberList(vector<int> & nlist)
+{
+
+  // Convert 
+  vector<int> n;
+  
+  //////////////////
+  // Check ranges
+
+  for (int i=0; i<nlist.size(); i++)
+    {
+      if ( nlist[i] == -1 ) 
+	{
+	  if ( nlist[i-1] > nlist[i+1] )
+	    {
+	      int tmp = nlist[i+1];
+	      nlist[i+1] = nlist[i-1];
+	      nlist[i-1] = tmp;
+	    }
+	}
+    }
+  
+
+  //////////////////
+  // Expand ranges
+  
+  for (int i=0; i<nlist.size(); i++)
+    {
+      
+      if ( nlist[i]>0 ) 
+ 	{
+	  // Only add valid codes
+	  if ( nlist[i] <= maxcat )
+	    n.push_back(nlist[i]);	  
+ 	}
+      else
+	{
+	  int start = nlist[i-1]+1;
+ 	  int end = nlist[i+1]-1;
+	  if ( end > maxcat )
+	    end = maxcat;
+
+ 	  for (int j=start; j<=end; j++)
+ 	    n.push_back(j);
+ 	}
+    }
+
+  // Sort and uniquify
+  stable_sort(n.begin(),n.end());
+  vector<int>::iterator ne = unique(n.begin(),n.end());
+  n.erase(ne, n.end());
+
+  // Shift to 0..N-1 coding
+  for (int i=0; i<n.size(); i++)
+    --n[i];
+
+
+  // Or is it a negative complement?
+  if ( negmode )
+    {
+
+      vector<bool> k(maxcat,false);
+      for (int i=0; i<n.size(); i++)
+	k[ n[i] ] = true;
+      
+      vector<int> n2 = n;
+      n.clear();
+      
+      for (int i=0; i<maxcat; i++)
+	{
+	  if ( ! k[i] ) 
+	    {
+	      n.push_back(i);
+	    }
+	}
+    }
+ 
+  return n;
+
+}
+
+
+vector<string> NList::tokenize(string s)
+{
+
+  vector<string> t;
+  
+  string word = "";
+  bool range_set = false;
+  bool number_given = false;
+  
+  for (int i=0; i<s.length(); i++)
+    {      
+
+      // Skip spaces
+      if (s[i] == ' ') 
+	continue;
+      
+      if ( s[i] == ',' || s[i] == range_char )
+	{
+
+	  // If we've built up a meaningful word,
+	  // we can add it now
+
+	  if ( word != "" )
+	    {
+	      t.push_back(word);
+	      word = "";
+	      number_given = true;
+	      range_set = false;
+	    }
+	  
+	  
+	  // Start a range? 
+	  if ( s[i]== range_char )
+	    {
+
+	      // Can't do twice
+	      if (range_set)
+		error("Invalid list: " + s + "\n");
+	      
+	      range_set = true;
+	      
+	      // But was a start point given? Make one 
+	      // if not
+
+	      if ( ! number_given )
+		{
+		  t.push_back("1");
+		  word="";
+		}
+	      
+	      number_given = false;
+	      
+	      t.push_back(range_string);
+	      
+	    }
+	  
+	  // And if the "-" is also the last 
+	  // character, we need an end point
+	  
+	  if ( s[i]== range_char && i == s.length()-1 )
+	    t.push_back( lastWord );
+	  
+	  // Here, fill in here
+	  if ( s[i]==',')
+	    {
+	      number_given = false;
+	      if ( range_set )
+		{
+		  range_set = false;
+		  t.push_back( lastWord );
+		}	  
+	    } 
+	}
+      else if ( i == s.length()-1 )
+	{
+	  // Is this a last number?
+	  t.push_back(word+s[i]);
+	  number_given = true;
+	}
+      else
+	word += s[i];
+    }
+
+  return t;
+}

Added: trunk/packages/plink/trunk/.pc/gcc43.patch/parse.cpp
===================================================================
--- trunk/packages/plink/trunk/.pc/gcc43.patch/parse.cpp	                        (rev 0)
+++ trunk/packages/plink/trunk/.pc/gcc43.patch/parse.cpp	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,3386 @@
+
+
+//////////////////////////////////////////////////////////////////
+//                                                              //
+//           PLINK (c) 2005-2008 Shaun Purcell                  //
+//                                                              //
+// This file is distributed under the GNU General Public        //
+// License, Version 2.  Please see the file COPYING for more    //
+// details                                                      //
+//                                                              //
+//////////////////////////////////////////////////////////////////
+
+
+#include <iostream>
+#include <string>
+#include <cmath>
+#include "options.h"
+#include "helper.h"
+
+
+void getOutputFilename(CArgs & a)
+{
+
+  ////////////////////////////////////////
+  // Insert commands from a file
+  
+  if (a.find("--script"))
+    {      
+      string f = a.value("--script");
+      a.fromScript(f);
+    }
+
+  if (a.find("--rerun"))
+    {      
+      string f = a.value("--rerun");
+      a.fromPriorLog(f);
+    }
+
+  if (a.find("--out")) 
+    {
+      par::output_file_name = a.value("--out");
+    }
+  
+  if (a.find("--gplink")) 
+    {
+      if ( par::cli )
+	error("Cannot specify --gplink and --interactive");
+      par::silent = true;
+      par::gplink = true;
+    }
+  
+  if (a.find("--silent")) 
+    {
+      if ( par::cli )
+	error("Cannot specify --silent and --interactive");
+
+      par::silent = true;
+    }
+
+  if (a.find("--interactive")) 
+    {
+      if ( a.find("--script") )
+	error("Cannot specify --script and --interactive");      
+      par::cli = true;
+    }
+}
+
+void setOptions(CArgs & a)
+{
+
+
+  /////////////////////////////////////
+  // Web-based functions
+  
+  if (a.find("--noweb")) par::web_check = false;
+
+  if (a.find("--lookup"))
+    {
+      par::lookup = true;
+      par::lookup_single_snp = true;
+      par::lookup_snp = a.value("--lookup");
+    }
+
+  if (a.find("--lookup-list"))
+    {
+      par::lookup = true;
+      par::lookup_to_file = true;
+      par::lookup_single_snp = false;
+      par::lookup_snp = a.value("--lookup-list");
+    }
+
+  if (a.find("--lookup-save"))
+    par::lookup_to_file = true;
+
+  if (a.find("--lookup-gene"))
+    {
+      par::lookup = true;
+      par::lookup_to_file = true;
+      par::lookup_gene = true;
+      par::lookup_gene_name = a.value("--lookup-gene");
+    }
+
+  if (a.find("--R"))
+    {
+      par::run_R_script = true;
+      par::R_script = a.value("--R");
+    }
+
+  if (a.find("--R-debug"))
+    par::run_R_write_script = true;
+  
+  if (a.find("--R-chisq"))
+    par::run_R_chisq = true;
+
+  if (a.find("--R-z"))
+    par::run_R_z = true;
+
+  if (a.find("--R-nsnps"))
+    par::run_R_nsnps = a.value_int("--R-nsnps");
+
+  if (a.find("--seed"))
+    par::random_seed = a.value_lui("--seed");      
+
+  ////////////////////////////////////////
+  // A data-generation option? 
+  
+  bool makedata = false;
+  
+  if (a.find("--recode")) 
+    {
+      makedata = true;
+      par::recode = true;
+      // and unless otherwise specified, set GENO = 1 and MAF = 0
+      if (!a.find("--maf")) par::min_af = 0.0;
+      if (!a.find("--geno")) par::MAX_GENO_MISSING = 1;
+      if (!a.find("--mind")) par::MAX_IND_MISSING = 1;
+    }
+  
+  if (a.find("--recode12")) 
+    {
+      makedata = true;
+      par::recode_12 = true;
+      // and unless otherwise specified, set GENO = 1 and MAF = 0
+      if (!a.find("--maf")) par::min_af = 0.0;
+      if (!a.find("--geno")) par::MAX_GENO_MISSING = 1;     
+      if (!a.find("--mind")) par::MAX_IND_MISSING = 1;
+    }
+  
+  if (a.find("--recodeHV")) 
+    {
+      makedata = true;
+      par::recode_HV = true;
+      // and unless otherwise specified, set GENO = 1 and MAF = 0
+      if (!a.find("--maf")) par::min_af = 0.0;
+      if (!a.find("--geno")) par::MAX_GENO_MISSING = 1;     
+      if (!a.find("--mind")) par::MAX_IND_MISSING = 1;
+    }
+  
+  if (a.find("--recode-whap")) 
+    {
+      makedata = true;
+      par::recode_whap = true;
+      // and unless otherwise specified, set GENO = 1 and MAF = 0
+      if (!a.find("--maf")) par::min_af = 0.0;
+      if (!a.find("--geno")) par::MAX_GENO_MISSING = 1;     
+      if (!a.find("--mind")) par::MAX_IND_MISSING = 1;
+    }
+
+  if (a.find("--recode-fastphase")) 
+    {
+      makedata = true;
+      par::recode_fastphase = true;
+      // and unless otherwise specified, set GENO = 1 and MAF = 0
+      if (!a.find("--maf")) par::min_af = 0.0;
+      if (!a.find("--geno")) par::MAX_GENO_MISSING = 1;     
+      if (!a.find("--mind")) par::MAX_IND_MISSING = 1;
+    }
+
+  if (a.find("--recode-structure")) 
+    {
+      makedata = true;
+      par::recode_structure = true;
+      // and unless otherwise specified, set GENO = 1 and MAF = 0
+      if (!a.find("--maf")) par::min_af = 0.0;
+      if (!a.find("--geno")) par::MAX_GENO_MISSING = 1;     
+      if (!a.find("--mind")) par::MAX_IND_MISSING = 1;
+    }
+
+  if (a.find("--recode-bimbam")) 
+    {
+      makedata = true;
+      par::recode_bimbam = true;
+      // and unless otherwise specified, set GENO = 1 and MAF = 0
+      if (!a.find("--maf")) par::min_af = 0.0;
+      if (!a.find("--geno")) par::MAX_GENO_MISSING = 1;     
+      if (!a.find("--mind")) par::MAX_IND_MISSING = 1;
+    }
+  
+  if (a.find("--recodeAD")) 
+    {
+      makedata = true;
+      par::recode_AD = true;
+      // and unless otherwise specified, set GENO = 1 and MAF = 0
+      if (!a.find("--maf")) par::min_af = 0.0;
+      if (!a.find("--geno")) par::MAX_GENO_MISSING = 1;     
+      if (!a.find("--mind")) par::MAX_IND_MISSING = 1;
+    }
+  
+  
+  if (a.find("--recodeA")) 
+    {
+      makedata = true;
+      par::recode_AD = true;
+      par::recode_AD_Aonly = true;
+      // and unless otherwise specified, set GENO = 1 and MAF = 0
+      if (!a.find("--maf")) par::min_af = 0.0;
+      if (!a.find("--geno")) par::MAX_GENO_MISSING = 1;     
+      if (!a.find("--mind")) par::MAX_IND_MISSING = 1;
+    }
+  
+  if (a.find("--recode-allele"))
+    {
+      if ( ! par::recode_AD )
+	error("Must specify --recodeA or --recodeAD with --recode-allele");
+      par::recode_allele_coding = true;
+      par::recode_allele_coding_file = a.value("--recode-allele");
+    }
+  
+  if (a.find("--make-bed")) 
+    { 
+      makedata = true;
+      par::write_bitfile = true; 
+      
+      // and unless otherwise specified, set GENO = 1 and MAF = 0
+      if (!a.find("--maf")) par::min_af = 0.0;
+      if (!a.find("--geno")) par::MAX_GENO_MISSING = 1;
+      if (!a.find("--mind")) par::MAX_IND_MISSING = 1;
+    } 
+    
+  
+  //////////////////////////////////////////////
+  // Modifiers of main data generation commands
+
+  if (a.find("--alleleACGT")) par::recode_ACGT = true;
+  
+  if (a.find("--allele1234")) par::recode_1234 = true;
+
+  if (a.find("--transpose"))
+    {
+      if ( ! ( a.find("--recode") || a.find("--recode12")  ) )
+	error("--transpose requires --recode or --recode12");
+      par::recode_transpose = true;
+    }
+  
+  if (a.find("--tab"))
+    {
+      if ( ! makedata ) 
+	error("You can only specify --tab with a --recode* option");
+      par::recode_delimit = "\t";
+    }
+    
+  
+  ////////////////////////////////////////////////////
+  // Convenience functions and obligatory missingness
+  
+  // Zero out genotypes for a particular SNP / cluster
+  
+  if ( a.find("--zero-cluster") )
+    {
+      if ( ! a.find("--within") )
+	error("You must specify --within with --zero-cluster");
+      par::zero_cluster = true;
+      par::zero_cluster_filename = a.value("--zero-cluster");
+    }
+  
+  // Perform genotyping rate calculations, but allow for 
+  // obligatory missingness
+    
+  if ( a.find("--oblig-missing") )
+    {
+      if ( ! a.find("--oblig-clusters") )
+	error("You must specify --oblig-clusters with --oblig-missing");
+      par::oblig_missing = true;
+      par::oblig_missing_filename = a.value("--oblig-missing");
+    }
+  
+  if ( a.find("--oblig-clusters") )
+    {
+      if ( ! a.find("--oblig-missing") )
+	error("You must specify --oblig-missing with --oblig-clusters");
+      par::oblig_clusters_filename = a.value("--oblig-clusters");
+    }
+
+  // Multiple category phenotype
+
+  if ( a.find("--loop-assoc") )
+    {
+      if ( a.find("--within") )
+	error("You cannot specify --within with --loop-assoc");
+      
+      par::all_pheno = true;
+      par::assoc_test = true;
+      par::loop_over = true;
+      par::include_cluster_from_file = true;
+      par::include_cluster_filename = a.value("--loop-assoc");
+    }
+  
+    
+  
+  ////////////////////////////////////////
+  // TODO list
+  
+  if (a.find("--todo"))
+    {
+      cout << "TODO list\n"
+	   << " * Make --min/--max thresholds apply w/ read-segment\n"
+	   << " * Odds ratio for DFAM\n"
+	   << " * X chromosome phasing\n"
+	   << " * Check Hotelling's T2 imputation of missing genotypes\n"
+	   << " * Add improved familial phasing to haplotype tests\n"
+	   << " * Add OR and CI to haplotype tests\n"
+	   << " * Add CMH and/or permutation to haplotype tests\n"
+	   << " \n"
+	   << " * Include weighted association test, for haplotypes (effN)\n"
+	   << " * Phasing option to merge with current data\n"
+	   << " \n"
+	   << " * Check new X models\n"
+	   << " * Check new MM tests\n"
+	   << " \n";
+      exit(0);
+    }
+  
+  
+  ///////////////////////////////////////
+  // Output options
+
+  if (a.find("--flag")) par::flag = true;
+
+  if (a.find("--verbose")) par::verbose = true;
+
+  if (a.find("--pedigree")) par::dumpped = true;
+
+  if (a.find("--debug")) par::debug = true;
+
+  
+  ///////////////////////////////////////
+    // IBD analyses, output options
+     
+    if (a.find("--multi")) par::multi_output = true;
+    
+    if (a.find("--gmulti")) par::gmulti_output = true;
+    
+    if (a.find("--summarise-ibd")) par::summary_ibd_output = true;
+
+  if (a.find("--genome")) 
+    {
+      // By default, include everybody
+      if (!a.find("--min"))
+	{
+	  par::MIN_PIHAT = 0;
+	  par::pihat_filter = false;
+	}
+
+      par::genome_output = true;
+    }
+
+  if (a.find("--impossible")) 
+    {
+      if (!a.find("--genome"))
+	error("Can only specify --impossible with --genome");
+      par::show_impossible_IBD = false;
+    }
+  
+  if (a.find("--nudge")) 
+    {
+      if (!a.find("--genome"))
+	error("Can only specify --nudge with --genome");
+      if (a.find("--impossible"))
+	error("Cannot specify --impossible and --nudge together");
+      par::nudge = true;
+    }
+
+  if (a.find("--unbounded")) 
+    { 
+	par::bound = false; 
+	par::MIN_PIHAT = -1;
+	par::MAX_PIHAT = 1;
+    }
+
+  if (a.find("--genome-lists")) 
+    {
+      if ( ! ( a.find("--genome") || a.find("--segment") ) )
+	error("Must specify --genome or --segment with --genome-lists");      
+      par::genome_2sets = true;
+      vector<string> s = a.value("--genome-lists",2);
+      par::genome_setlist1 = s[0];
+      par::genome_setlist2 = s[1];
+    }
+
+  if (a.find("--segment-within"))
+    {
+      if ( !a.find("--within"))
+	error("You need to specify a --within {clusterfile}");
+      par::IBD_within = true;
+    }
+  
+  if (a.find("--genome-test")) 
+    {
+      par::genome_test = true;
+      par::genome_test_threshold = a.value_double("--genome-test");
+      par::plink = true;
+      par::permute = true;
+      par::adaptive_perm = false;
+      par::replicates = 100000;
+    }
+
+  if (a.find("--ibs-test")) 
+    {
+      par::ibs_test = true;
+      par::permute = true;
+      par::adaptive_perm = false;
+      par::replicates = 100000;
+    }
+
+  if (a.find("--ibs-test2")) 
+    {
+      par::ibs_test = true;
+      par::ibs_test_method2 = true;
+      par::permute = true;
+      par::adaptive_perm = false;
+      par::replicates = 100000;
+    }
+  
+
+  if (a.find("--segment-match-snp")) 
+    par::genome_test_min_snp = a.value_int("--segment-match-snp");
+    
+
+
+
+  ///////////////////////////////////////////
+  // WGAS main options: summary stats and QC
+
+
+  if (a.find("--missing")) { par::report_missing = true; } 
+
+  if (a.find("--mendel")) { par::MENDEL_report = true; } 
+
+  if (a.find("--hardy")) par::HWD_report = true;
+
+  if (a.find("--hardy2")) par::HWD_report = par::HWD_standard = true;
+
+  if (a.find("--het")) par::inbreeding = true;
+  
+  if (a.find("--check-sex"))
+    par::check_sex = true;
+  
+  if (a.find("--impute-sex"))
+    par::check_sex = par::impute_sex = true;
+
+  if (a.find("--test-missing")) { par::test_missing = true; } 
+
+  if (a.find("--test-mishap")) { par::mishap_test = true; } 
+
+  if (a.find("--mishap-window")) 
+    { 
+      par::mishap_test = true; 
+      par::mishap_window = a.value_int("--mishap-window");
+    } 
+
+  if (a.find("--score"))
+    {
+      par::score_risk = true;
+      par::score_risk_file = a.value("--score");
+    }
+
+
+
+  ////////////////////////////////////////////////////////////////
+  // Proxy association methods
+
+  if (a.find("--proxy-assoc"))
+    {
+      par::proxy_assoc = true;
+      par::proxy_CC = true;
+      par::proxy_assoc_snp = a.value("--proxy-assoc");
+      if ( par::proxy_assoc_snp == "all" || par::proxy_assoc_snp == "ALL" )
+	par::proxy_all = true;
+
+      if ( a.find("--proxy-glm") )
+	par::proxy_glm = true;
+    }
+
+
+  if (a.find("--proxy-drop"))
+    {
+      if ( a.find("--proxy-impute"))
+	error("Cannot have --proxy-drop and --proxy-impute (already implied)");
+      par::proxy_leave_out = true;
+    }
+  
+  if (a.find("--proxy-exclude"))
+    {
+      par::proxy_exclude = true;
+      par::proxy_exclude_from_file = false;
+      par::proxy_exclude_list = a.value("--proxy-exclude");
+    }
+  else if (a.find("--proxy-exclude-list"))
+    {
+      par::proxy_exclude = true;
+      par::proxy_exclude_from_file = true;
+      par::proxy_exclude_list = a.value("--proxy-exclude-list");
+    }
+
+  if (a.find("--proxy-include-reference"))
+    par::proxy_include_reference = true;
+
+  if (a.find("--proxy-impute"))
+    {
+      par::proxy_assoc = true;
+      par::proxy_impute = true;
+      par::proxy_assoc_snp = a.value("--proxy-impute");
+      if ( par::proxy_assoc_snp == "all" || par::proxy_assoc_snp == "ALL" )
+	par::proxy_all = true;
+      
+      if ( a.find("--proxy-dosage") )
+	par::proxy_record_dosage = true;
+
+      if ( a.find("--proxy-replace") )
+	par::proxy_impute_replace = true;
+
+//       if ( a.find("--proxy-preserve") )
+// 	par::proxy_impute_preserve_genotyped = true;
+
+      if ( a.find("--proxy-genotypic-concordance") )
+	par::proxy_impute_genotypic_concordance = true;
+
+    }
+
+  if (a.find("--proxy-error")) par::proxy_error = true;
+    
+
+  if (a.find("--proxy-impute-threshold"))
+    par::proxy_impute_threshold = a.value_double("--proxy-impute-threshold");
+
+  if (a.find("--proxy-tdt"))
+    {
+      par::proxy_assoc = true;
+      par::proxy_TDT = true;
+      par::proxy_assoc_snp = a.value("--proxy-tdt");
+      if ( par::proxy_assoc_snp == "all" || par::proxy_assoc_snp == "ALL" )
+	par::proxy_all = true;
+    }
+  
+  if ( par::proxy_assoc ) 
+    {
+      // Reset default missing rate per individual
+      // per haplotype (more relevant if the window
+      // size is small (i.e. to goal is not to discard
+      // too many / any individuals, but rely on E-M 
+      // phasing to reconstruct missing genotypes. Normally
+      // the default value here is 0.5;  it can be modified as
+      // --hap-miss option is below this one
+      
+      par::hap_missing_geno = 0.9;
+
+    }
+
+  if (a.find("--proxy-verbose"))
+    par::proxy_full_report = true;
+
+  if (a.find("--proxy-window"))
+    par::proxy_window = a.value_int("--proxy-window");
+
+  if (a.find("--proxy-flanking"))
+    {
+      if ( par::proxy_all ) 
+	error("Cannt specify --proxy-flanking with >1 reference SNP");
+
+      par::proxy_list = true;
+      par::proxy_list_file = a.value("--proxy-flanking");
+    }
+
+  if (a.find("--proxy-list"))
+    {
+      if ( a.find("--proxy-flanking"))
+	error("Cannt specify --proxy-flanking with >1 reference SNP");
+
+      par::proxy_all_list = true;
+      par::proxy_all_list_file = a.value("--proxy-list");
+    }
+
+  if (a.find("--proxy-kb"))
+    par::proxy_kb = a.value_double("--proxy-kb");
+
+  if (a.find("--proxy-sub-r2"))
+    par::proxy_r2 = a.value_double("--proxy-sub-r2");
+
+  if (a.find("--proxy-maf"))
+    par::proxy_maf = a.value_double("--proxy-maf");
+
+  if (a.find("--proxy-geno"))
+    par::proxy_geno = a.value_double("--proxy-geno");
+
+  if (a.find("--proxy-mhf"))
+    par::proxy_mhf = a.value_double("--proxy-mhf");
+
+  if (a.find("--proxy-sub-maxsnp"))
+    par::proxy_maxhap = a.value_int("--proxy-sub-maxsnp");
+  
+  if (a.find("--proxy-no-r2-filter"))
+    par::proxy_r2_filter = false;
+  
+  if (a.find("--proxy-r2"))
+    {
+      par::proxy_r2_filter = true;
+      vector<string> s = a.value("--proxy-r2",3);
+      par::proxy_r2_filter_A = getDouble(s[0], "--proxy-r2");
+      par::proxy_r2_filter_B = getDouble(s[1], "--proxy-r2");
+      par::proxy_r2_filter_C = getDouble(s[2], "--proxy-r2");           
+    }
+
+  if (a.find("--proxy-maxsnp"))
+    par::proxy_snp_filter = a.value_int("--proxy-maxsnp");
+  
+  if (a.find("--proxy-show-proxies"))
+    par::proxy_list_proxies = true;
+
+  if (a.find("--proxy-r2-reference-only"))
+    par::proxy_reference_only = true;
+  
+
+  ////////////////////////////////////////
+  // Segmental options
+  
+  //  --segment-match-snp
+  //  --homozyg
+  //  --homozyg-window-kb
+  //  --homozyg-window-snp
+  //  --homozyg-window-het
+  //  --homozyg-window-missing
+  //  --homozyg-snp
+  //  --homozyg-kb
+  //  --homozyg-density
+  //  --homozyg-gap
+  //  --homozyg-group
+  //  --homozyg-match
+  //  --homozyg-het
+  //  --homozyg-verbose
+
+  //  --segment
+  //  --segment-gap
+  //  --segment-length
+  //  --segment-thresholds
+  //  --segment-minimal
+
+  //  --segment-group
+  //  --segment-spanning
+  //  --segment-from
+  //  --segment-to
+  //  --segment-force
+  //  --segment-match
+  //  --segment-verbose
+
+  //  --pool-size 
+
+  // Read segments back in
+  //  --read-segment
+  //  --read-segment-minimal
+
+
+  //////////////////////////
+  // CNV/other segment types
+ 
+  if (a.find("--cnv-list"))
+    {
+      par::cnv_list = true;
+      par::cnv_listname = a.value("--cnv-list");
+
+      // Remove any missing individuals
+      if (!a.find("--cnv-missing-phenotypes"))
+	par::ignore_phenotypes = false;
+      
+      if (a.find("--cnv-make-map"))
+	par::cnv_makemap = true;
+
+      if (a.find("--cnv-write"))
+	{
+	  par::cnv_writelist = true;
+	  if (a.find("--with-phenotype"))
+	    par::dump_covar_with_phenotype = true;
+	}
+      
+      if (a.find("--cnv-intersect"))
+	{
+	  if ( a.find("--cnv-exclude") || 
+	       a.find("--cnv-count"))
+	    error("Cannot specify --cnv-count/intersect/exclude together");
+
+	  par::cnv_intersect = true;
+	  par::cnv_intersect_file = a.value("--cnv-intersect");
+	}
+
+      if (a.find("--cnv-exclude"))
+	{
+	  if ( a.find("--cnv-count") || 
+	       a.find("--cnv-intersect"))
+	    error("Cannot specify --cnv-count/intersect/exclude together");
+
+	  par::cnv_intersect = par::cnv_exclude = true;
+	  par::cnv_intersect_file = a.value("--cnv-exclude");
+	}
+
+      if (a.find("--cnv-count"))
+	{
+	  if ( a.find("--cnv-exclude") || 
+	       a.find("--cnv-intersect"))
+	    error("Cannot specify --cnv-count/intersect/exclude together");
+	  par::cnv_intersect = par::cnv_count = true;
+	  par::cnv_intersect_file = a.value("--cnv-count");
+	}
+      
+      if (a.find("--cnv-freq-exclude-above"))
+	{
+	  par::cnv_freq_include = true;
+	  par::cnv_freq_include_below = true;
+	  par::cnv_freq_include_cnt = a.value_int("--cnv-freq-exclude-above");
+	}
+      
+      if (a.find("--cnv-freq-exclude-below"))
+	{
+	  par::cnv_freq_include = true;
+	  par::cnv_freq_include_below = false;
+	  par::cnv_freq_include_cnt = a.value_int("--cnv-freq-exclude-below");
+	}      
+
+      if (a.find("--cnv-unique"))
+	{	  
+	  par::cnv_unique = true;
+	}
+
+      if (a.find("--cnv-report-regions") )
+	{
+	  if ( ! ( a.find("--cnv-intersect") || a.find("--cnv-exclude")) )
+	    error("Must specify either --cnv-intersect or --cnv-exclude with --cnv-report-regions");
+	  par::cnv_intersect_writeback = true;
+	}
+      
+      if (a.find("--cnv-overlap"))
+	{
+	  par::cnv_defined_overlap = true;
+	  par::cnv_overlap = a.value_double("--cnv-overlap");
+	}
+
+      if (a.find("--cnv-kb"))
+	par::cnv_min_kb = a.value_int("--cnv-kb");
+      if (a.find("--cnv-score"))
+	par::cnv_min_score = a.value_double("--cnv-score");
+      if (a.find("--cnv-sites"))
+	par::cnv_min_sites = a.value_int("--cnv-sites");
+
+      if (a.find("--cnv-max-kb"))
+	par::cnv_max_kb = a.value_int("--cnv-max-kb");
+      if (a.find("--cnv-max-score"))
+	par::cnv_max_score = a.value_double("--cnv-max-score");
+      if (a.find("--cnv-max-sites"))
+	par::cnv_max_sites = a.value_int("--cnv-max-sites");
+      
+      if (a.find("--cnv-del"))
+	par::cnv_del_only = true;
+      if (a.find("--cnv-dup"))
+	par::cnv_dup_only = true;
+     
+      if (a.find("--cnv-test-window"))
+	{
+	  par::seg_test_window = true;
+	  par::seg_test_window_bp = a.value_double("--cnv-test-window") * 1000;
+	}
+
+      if (a.find("--cnv-test-2sided"))
+	par::segment_test_1sided = false;
+
+      if (a.find("--cnv-indiv-perm"))
+	par::cnv_indiv_perm = true;
+
+      if (a.find("--cnv-drop-no-segment"))
+	par::cnv_drop_no_segment = true;
+
+      if (a.find("--merge") || a.find("--bmerge"))
+	error("Cannot specify --cnv-list and merge SNP data together");
+ 
+      if (a.find("--exclude") || a.find("--extract"))
+	error("Cannot specify --cnv-list and exclude/extract markers SNP data together");
+
+      if (a.find("--maf") || a.find("--geno") || a.find("--mind"))
+	error("Cannot specify --cnv-list and filter on SNP data together");
+
+    }
+
+  ///////////////////////
+  // Runs of homozygosity
+
+  if (a.find("--homozyg"))
+    {
+      par::homo_run = true;
+    }
+
+  if (a.find("--read-homozyg"))
+    {
+      par::homo_run = true;
+      par::read_segment_filename = a.value("--read-homozyg");
+      par::read_segment_file = true;
+    }
+
+  if (a.find("--homozyg-snp"))
+    {
+      par::homo_run = true;
+      par::homo_run_snps = true;
+      par::homo_run_length_snps = a.value_int("--homozyg-snp");
+    }
+
+  if (a.find("--homozyg-kb")) 
+  { 
+      par::homo_run = true;
+      par::homo_run_kb = true;
+      par::homo_run_length_kb = a.value_int("--homozyg-kb");
+    }
+
+  if (a.find("--homozyg-density")) 
+    { 
+      par::homo_run = true;
+      par::homo_run_density = a.value_double("--homozyg-density");
+    }
+
+  if (a.find("--homozyg-gap")) 
+    { 
+      par::homo_run = true;
+      par::homo_run_gap = a.value_int("--homozyg-gap");
+    }
+
+  if (a.find("--homozyg-window-snp")) 
+    { 
+      par::homo_run = true;
+      par::homo_windowSize = a.value_int("--homozyg-window-snp");
+    }
+  
+  if (a.find("--homozyg-window-kb")) 
+    { 
+      par::homo_run = true;
+      par::homo_windowKB = a.value_int("--homozyg-window-kb");
+    }
+    
+  if (a.find("--homozyg-window-het")) 
+    { 
+      par::homo_run = true;
+      par::homo_windowAllowedHet = a.value_int("--homozyg-window-het");
+    }
+    
+  if (a.find("--homozyg-window-missing")) 
+    { 
+      par::homo_run = true;
+      par::homo_windowAllowedMissing = a.value_int("--homozyg-window-missing");
+    }
+
+  if (a.find("--homozyg-window-threshold")) 
+    { 
+      par::homo_run = true;
+      par::homo_threshold = a.value_double("--homozyg-window-threshold");
+    }
+
+  if (a.find("--homozyg-group"))
+    {
+      par::homo_summary_allelic_match = true;
+      par::fuzzy_homo = 0.95;
+    }
+    
+  if (a.find("--homozyg-match"))
+    {
+      par::homo_summary_allelic_match = true;
+      par::fuzzy_homo = a.value_double("--homozyg-match");
+    }
+
+  if (a.find("--homozyg-het")) 
+    { 
+      if (! ( a.find("--homozyg-snp") ||
+	      a.find("--homozyg-kb") ) )
+	error("Must specify --homozyg-snp or --homozyg-kb with --homozyg-het");
+      par::homo_run_het = a.value_int("--homozyg-het");
+    }
+
+  if (a.find("--homozyg-verbose"))
+    par::homozyg_verbose = true;
+
+  if (a.find("--consensus-match"))
+    {
+      par::homo_run_consensus_match = true;
+    }
+
+  if (a.find("--pool-size"))
+    {
+      par::pool_size_min = a.value_int("--pool-size");
+    }
+  
+  if (a.find("--ibs")) par::ibs_run = true;
+
+  if (a.find("--ibs2")) par::ibs_run = par::ibs_2only = true;
+
+  if (a.find("--ibs-density")) 
+    {
+      par::ibs_run = true;
+      par::ibs_run_density = a.value_double("--ibs-density");
+    }
+
+  if (a.find("--ibs-kb")) 
+    {
+      par::ibs_run = true;
+      par::ibs_run_length_kb = a.value_int("--ibs-kb");
+    }
+
+  if (a.find("--ibs-snp")) 
+    {
+      par::ibs_run = true;
+      par::ibs_run_length_snps = a.value_int("--ibs-snp");
+    }
+
+//   static int ibs_inner_run_length_kb;
+
+//   if (a.find("--ibs-join-snp")) 
+//     {
+//       par::ibs_run = true;
+//       par::ibs_join_snp = a.value_int("--ibs-join-snp");
+//     }
+
+//   if (a.find("--ibs-join-snp")) 
+//     {
+//       par::ibs_run = true;
+//       par::ibs_join_snp = a.value_int("--ibs-join-snp");
+//     }
+
+//   if (a.find("--ibs-join-kb")) 
+//     {
+//       par::ibs_run = true;
+//       par::ibs_join_kb = a.value_int("--ibs-join-kb") * 1000;
+//     }
+
+
+  if (a.find("--ibs-gap")) 
+    {
+      par::ibs_run = true;
+      par::ibs_inter_snp_distance = a.value_int("--ibs-gap") * 1000;
+   }
+
+  if (a.find("--ibs-miss")) 
+    {
+      par::ibs_run = true;
+      par::ibs_run_missing = a.value_int("--ibs-miss");
+    }
+
+  if (a.find("--ibs-err")) 
+    {
+      par::ibs_run = true;
+      par::ibs_run_0 = a.value_int("--ibs-err");
+    }
+  
+  if (a.find("--miss-run-snps"))
+    {
+      par::miss_run = true;
+      par::miss_run_length = a.value_int("--miss-run-snps");
+    }
+  
+  if (a.find("--miss-run")) 
+    { 
+      cerr << "\n*** WARNING -- use --miss-run-snps N option instead\n\n";
+      par::miss_run = true;
+      par::miss_run_length_kb = true;
+      par::miss_run_length = a.value_int("--miss-run");
+    }
+
+  if (a.find("--miss-run-level"))
+    {
+      par::miss_run = true;
+      par::miss_run_level = a.value_double("--miss-run-level");
+    }
+
+
+  ///////////////////////////
+  // Segmental sharing tests
+  
+//   if (a.find("--plink")) 
+//     {
+//       par::plink = true;
+//       par::nudge = true;
+//     }
+
+  if (a.find("--segment")) 
+    {
+      par::plink = true;
+      par::nudge = true;
+      par::segment_output = true;
+    }
+
+  if (a.find("--segment-ibs"))
+    {
+      par::segment_validate = true; 
+    }
+
+  if (a.find("--segment-minimal")) 
+    {
+      par::plink = true;
+      par::nudge = true;
+      par::segment_output = true;
+      par::segment_minimal = true;
+    }
+  
+  if (a.find("--segment-test-individual"))
+    {
+      // Instead of pairwise Case-Case versus non-Case-Case, 
+      // just count the number of segs that any one individual
+      // has, and compare count in cases to count in controls
+      par::segment_test_individual = true;
+      if (a.find("--specific"))
+	par::segment_test_specific_segs = true;
+    }
+
+  if (a.find("--segment-test-ignore-discordant"))
+    {
+      // Pairwise Case-Case versus Control-Control
+      par::segment_test_ignore_discordant = true;
+    }
+
+  if (a.find("--segment-test-fisher"))
+    {
+      par::segment_test_fisher = true;
+    }
+
+  if (a.find("--segment-test-2sided"))
+    par::segment_test_1sided = false;
+
+  if (a.find("--segment-group")) 
+    {
+      // Use HBD segment match routine, but without
+      // allelic identity option
+      par::segment_overlap = true;
+      par::homo_summary_allelic_match = false;
+      par::fuzzy_homo = 0.95; 
+    }
+
+   if (a.find("--segment-spanning")) 
+     {
+       
+//        if (!a.find("--segment-group"))
+// 	 error("Must specify --segment-group for --segment-spanning\n");
+       
+       par::segment_overlap = true;
+       par::homo_summary_allelic_match = false;
+       par::fuzzy_homo = 0.95;        
+       par::segment_m1 = par::segment_m2 = a.value("--segment-spanning");
+     }
+
+   if (a.find("--segment-from")) 
+     {
+       if (!a.find("--segment-group"))
+	 error("Must specify --segment-group for --segment-from\n");
+       par::segment_m1 = a.value("--segment-from");
+     }
+
+   if (a.find("--segment-to")) 
+     {
+       if (!a.find("--segment-group"))
+	 error("Must specify --segment-group for --segment-to\n");
+       par::segment_m2 = a.value("--segment-to");
+     }
+
+   if (a.find("--segment-force"))
+     {
+       if (! ( a.find("--segment-from") && a.find("--segment-to") ) )
+	 error("Can only use --segment-force with --segment-from/to \n");
+       par::force_span = true;
+     }
+
+  if (a.find("--segment-match")) 
+    {
+      // Use HBD segment match routine, but without
+      // allelic identity option
+      par::segment_overlap = true;
+      par::homo_summary_allelic_match = true;
+      par::fuzzy_homo = a.value_double("--segment-match"); 
+    }
+
+  if (a.find("--segment-verbose"))
+    par::segment_verbose = true;
+
+  if (a.find("--read-segment"))
+    {
+      if (par::segment_output)
+	error("Cannot specify both --segment and --read-segment\n");
+      par::read_segment_filename = a.value("--read-segment");
+      par::read_segment_file = true;
+      par::plink = true;
+      par::segment_output = true;
+    }
+
+  if (a.find("--read-segment-minimal"))
+    {
+      if (par::segment_output) 
+	error("Cannot specify both --segment and --read-segment\n");
+      par::read_segment_filename = a.value("--read-segment-minimal");
+      par::read_segment_file = true;
+      par::plink = true;
+      par::segment_output = true;
+      par::segment_minimal = true;
+    }
+
+  if (a.find("--segment-gap")) 
+    {
+      par::segment_output = true;
+      par::segment_inter_snp_distance = a.value_int("--segment-gap");
+    }
+
+  if (a.find("--segment-length")) 
+    {
+      // Min length in kb, convert to bp
+      par::segment_length = a.value_int("--segment-length") * 1000;
+    }
+  
+  if (a.find("--segment-snp")) 
+    {
+      // Min length in SNPs
+      par::segment_snp = a.value_int("--segment-snp");
+    }
+
+  if (a.find("--segment-thresholds"))
+    {
+      par::segment_output = true;
+      vector<string> s = a.value("--segment-thresholds",2);
+      par::segment_threshold_start = getDouble(s[0], "--segment-thresholds");
+      par::segment_threshold_finish = getDouble(s[1], "--segment-thresholds");
+    }
+
+
+  //////////////////////////
+  // Misc, external functions
+
+  if (a.find("--rare-test"))
+    {
+      vector<string> s = a.value("--rare-test",2);
+      par::rarer_maf_threshold = getDouble(s[0], "--rare-test");
+      par::rarer_dist_threshold = getDouble(s[1], "--rare-test") * 1000;
+      par::rare_test = true;
+    }
+
+
+  //////////////////////////
+  // Association testing
+  
+  if (a.find("--assoc")) par::assoc_test = true; 
+
+  if (a.find("--qt-means")) 
+    {
+      if ( ! a.find("--assoc"))
+	error("Can only specify --qt-means with --assoc for a QTL test");
+      par::qt_means = true;
+    }
+
+  if (a.find("--logistic")) par::assoc_test = par::assoc_glm = true;
+
+  if (a.find("--linear")) par::assoc_test = par::assoc_glm = true;
+
+  if (a.find("--no-snp")) par::assoc_glm_without_main_snp = true;
+
+  if (a.find("--vif")) par::vif_threshold = a.value_double("--vif");
+  
+  if (a.find("--genotypic")) 
+    {
+      if ( a.find("--hethom"))
+	par::twoDFmodel_hethom = true;
+
+      par::twoDFmodel = true;
+    }
+
+  if (a.find("--interaction")) par::simple_interaction = true;
+
+  if (a.find("--parameters"))
+    {
+      string ilist = a.value("--parameters");
+      par::parameter_list = parse2int(ilist);
+      par::glm_user_parameters = true;
+    }
+
+  if (a.find("--tests"))
+    {
+      string ilist = a.value("--tests");
+      par::test_list = parse2int(ilist);
+      par::glm_user_test = true;
+    }
+
+  if (a.find("--condition"))
+    {
+      if (! ( a.find("--linear") || 
+	      a.find("--logistic") || 
+	      a.find("--proxy-glm") || 
+	      a.find("--chap")) )
+	error("Can only use --condition with --linear, --logistic, --proxy-glm or --chap");
+
+      par::conditioning_snp_single = true;
+      par::conditioning_snps = true;
+      par::conditioning_snp_name = a.value("--condition");
+    }
+
+  if (a.find("--condition-list"))
+    {
+      if ( ! ( a.find("--linear") || a.find("--logistic") || a.find("--chap")) )
+	error("Can only use --condition-list with --linear, --logistic or --chap");
+
+      par::conditioning_snps = true;
+      par::conditioning_snps_file = a.value("--condition-list");
+    }
+
+  if (a.find("--test-all")) par::test_full_model = true;
+
+  if (a.find("--sex"))
+    par::glm_sex_effect = true;
+
+  if (a.find("--no-x-sex"))
+    par::glm_no_auto_sex_effect = true;
+  
+  if (a.find("--xchr-model"))
+    {
+      par::xchr_model = a.value_int("--xchr-model");
+      if (par::xchr_model < 0 || par::xchr_model >4)
+	error("--xchr-model must have a value between 1 and 4");
+    }
+
+  if (a.find("--dominant"))
+    {
+      if ( ! ( a.find("--linear") || a.find("--logistic")) )
+	error("Can only use --condition-list with --linear or --logistic");
+      if (a.find("--genotypic"))
+	error("Cannot specify --dominant and --genotypic together");
+      par::glm_dominant = true;
+      
+      // Only consider autosomes
+      par::xchr_model = 0; 
+    }
+
+  if (a.find("--recessive"))
+    {
+      if ( ! ( a.find("--linear") || a.find("--logistic")) )
+	error("Can only use --condition-list with --linear or --logistic");
+      if (a.find("--genotypic"))
+	error("Cannot specify --recessive and --genotypic together");
+      if (a.find("--dominant"))
+	error("Cannot specify --recessive and --dominant together");
+      par::glm_recessive = true;
+      
+      // Only consider autosomes
+      par::xchr_model = 0; 
+    }
+
+  if (a.find("--qfam")) 
+    {
+
+      if (a.find("--within"))
+	error("Cannot specify --within and --qfam together");
+      if (a.find("--family"))
+	error("Cannot specify --family and --qfam together");	
+      if (a.find("--genedrop"))
+	error("Cannot specify --genedrop and --qfam together");
+
+      par::QTDT_test = true;
+      par::assoc_test = true;
+      par::QFAM_within1 = true;
+    } 
+
+  if (a.find("--qfam-total")) 
+    {
+   
+      if (a.find("--within"))
+	error("Cannot specify --within and --qfam-total together");
+      if (a.find("--family"))
+	error("Cannot specify --family and --qfam-total together");	
+      if (a.find("--genedrop"))
+	error("Cannot specify --genedrop and --qfam-total together");
+
+      par::QTDT_test = true;
+      par::assoc_test = true; 
+      par::QFAM_total = true;
+    }
+
+  if (a.find("--qfam-between")) 
+    {
+   
+      if (a.find("--within"))
+	error("Cannot specify --within and --qfam-between together");
+      if (a.find("--family"))
+	error("Cannot specify --family and --qfam-between together");	
+      if (a.find("--genedrop"))
+	error("Cannot specify --genedrop and --qfam-between together");
+
+      par::QTDT_test = true;
+      par::assoc_test = true; 
+      par::QFAM_between = true;
+    }
+
+  if (a.find("--qfam-parents")) 
+    {
+ 
+      if (a.find("--within"))
+	error("Cannot specify --within and --qfam-parents together");
+      if (a.find("--family"))
+	error("Cannot specify --family and --qfam-parents together");	
+      if (a.find("--genedrop"))
+	error("Cannot specify --genedrop and --qfam-parents together");
+      
+      par::QTDT_test = true;
+      par::assoc_test = true; 
+      par::QFAM_within2 = true;
+    }
+
+      
+  if (a.find("--mh") || a.find("--mh1")) par::CMH_test_1 = par::assoc_test = true;
+  if (a.find("--mh-ord")) par::CMH_test_ORD = par::assoc_test = true;
+  if (a.find("--mh2")) par::CMH_test_2 = par::assoc_test = true;
+
+  if (a.find("--bd")) 
+    {
+      par::CMH_test_1 = par::assoc_test = true;
+      par::breslowday = true;
+    }
+
+  if (a.find("--homog")) par::assoc_test = par::OR_homog_test = true;
+
+  if (a.find("--model") || 
+      a.find("--model-dom") ||
+      a.find("--model-rec") ||
+      a.find("--model-trend") ||
+      a.find("--model-gen") )    
+    { 
+      par::assoc_test = true; 
+      par::full_model_assoc = true; 
+      
+      if (a.find("--model-gen")) par::model_perm_gen = true;
+      else if (a.find("--model-dom")) par::model_perm_dom = true;
+      else if (a.find("--model-rec")) par::model_perm_rec = true;
+      else if (a.find("--model-trend")) par::model_perm_trend = true;
+      else par::model_perm_best = true;
+
+      if ( (par::model_perm_gen || par::model_perm_best ) 
+	   && a.find("--adjust") )
+	error("Cannot specific --model-gen or --model-best with --adjust\n"
+	      "Add --model-dom, --model-rec or --model-trend instead");
+
+    }
+
+  if (a.find("--fisher"))
+    {
+      par::assoc_test = true; 
+      par::fisher_test = true;
+      par::min_geno_cell = 0;
+    }
+
+  if (a.find("--cell"))
+    par::min_geno_cell = a.value_int("--cell");
+
+  if (a.find("--gxe")) 
+    { 
+      if (!a.find("--covar")) 
+	error ("--covar {filename} must be specified with --gxe");
+      par::assoc_gxe = true; 
+    } 
+  
+  if (a.find("--tdt")) 
+    {
+      par::TDT_test = true;
+      par::perm_TDT_basic = true;
+      par::perm_TDT_parent = false;
+    }
+
+  if (a.find("--mating"))
+    {
+      par::TDT_test = true;
+      par::mating_tests = true;
+    }
+
+  if (a.find("--dfam"))
+    {
+      if ( a.find("--family") )
+	error("Cannot specify --family with --dfam\n");
+
+      par::TDT_test = true;
+      par::sibTDT_test = true;
+    }
+
+  if (a.find("--dfam-no-tdt"))
+    par::dfam_tdt = false;
+
+  if (a.find("--dfam-no-sibs"))
+    par::dfam_sibs = false;
+  
+  if (a.find("--dfam-no-unrelateds"))
+    par::dfam_unrelateds = false;
+  
+  if (a.find("--parentdt1")) 
+    {
+      par::TDT_test = true;
+      par::perm_TDT_basic = false;
+      par::perm_TDT_parent = true;
+    }
+
+  if (a.find("--parentdt2")) 
+    {
+      par::TDT_test = true;
+      par::perm_TDT_basic = false;
+      par::perm_TDT_parent = false;
+    }
+
+  if (a.find("--poo"))
+    {
+      if (!a.find("--tdt"))
+	error("Parent-of-origin analysis requires --tdt option");
+      
+      if (a.find("--hap-tdt"))
+	error("Parent-of-origin analysis not yet implemented for haplotypic TDT");
+      
+      par::TDT_test = true;
+      par::parent_of_origin = true;
+
+      // flavour of permutation?
+      if (a.find("--pat"))
+	{
+	  par::perm_POO_poo = false;
+	  par::perm_POO_pat = true;
+	}
+      else if (a.find("--mat"))
+	{
+	  par::perm_POO_poo = false;
+	  par::perm_POO_mat = true;
+	}
+      else if (a.find("--best"))
+	{
+	  par::perm_POO_poo = false;
+	  par::perm_POO_best = true;
+	}
+    }
+
+  
+
+      
+  if (a.find("--sharing")) par::ibs_sharing_test = true;
+  
+  if (a.find("--boot")) par::boot = true;
+  
+  if (a.find("--r")) 
+    {
+      par::disp_r1 = true;
+        if ( ! a.find("--matrix") )
+	par::disp_r_window = true;
+    }
+
+  if (a.find("--r2")) 
+    {
+      par::disp_r2 = true;
+      if ( ! a.find("--matrix") )
+	par::disp_r_window = true;
+    }
+
+  if (a.find("--ld"))
+    {
+      par::calc_SNPSNP_LD = true;
+      vector<string> s = a.value("--ld",2);
+      par::ld_SNP1 = s[0];
+      par::ld_SNP2 = s[1];
+    }
+
+  if (a.find("--ld-window"))
+    {
+      if (a.find("--matrix"))
+	error("Cannot specify --matrix and --ld-window together\n");
+      par::disp_r_window = true;
+      par::disp_r_window_snp = a.value_int("--ld-window");      
+    }
+
+  if (a.find("--ld-window-kb"))
+    {
+      if (a.find("--matrix"))
+	error("Cannot specify --matrix and --ld-window together\n");
+      par::disp_r_window = true;
+      // Store in base-pair units
+      par::disp_r_window_kb = a.value_int("--ld-window-kb") * 1000;      
+    }
+
+  if (a.find("--ld-window-r2"))
+    {
+      if (a.find("--matrix"))
+	error("Cannot specify --matrix and --ld-window together\n");
+      par::disp_r_window = true;
+      par::disp_r_window_r2 = a.value_double("--ld-window-r2");      
+    }
+
+  if (a.find("--indep"))
+    {
+      if (makedata)
+	{
+	  string msg = "Cannot specify --indep with --make-bed or --recode\n";
+	  msg += "    use --extract/--exclude with *.prune.in/*.prune.out files";
+ 	  error(msg);
+	}
+      
+      par::prune_ld = true;
+      vector<string> s = a.value("--indep",3);
+      par::prune_ld_win = getInt(s[0].c_str(),"--indep");
+      par::prune_ld_step = getInt(s[1].c_str(),"--indep");
+      par::prune_ld_vif = getDouble(s[2].c_str(),"--indep");
+      
+      if (par::prune_ld_win<2)
+	error("Cannot have a window size < 2 for --indep {window} {step} {VIF}");
+
+      if (par::prune_ld_step<1)
+	error("Cannot have a window step < 1 for --indep {window} {step} {VIF}");
+
+      if (par::prune_ld_vif<1)
+	error("Cannot have a VIF threshold < 1 for --indep {window} {step} {VIF}");
+
+    }
+
+  if (a.find("--indep-pairwise"))
+    {
+      if (makedata) 
+        {
+          string msg = "Cannot specify --indep with --make-bed or --recode\n";
+          msg += "    use --extract/--exclude with *.prune.in/*.prune.out files";
+          error(msg);
+        }
+
+      par::prune_ld = true;
+      par::prune_ld_pairwise = true;
+      vector<string> s = a.value("--indep-pairwise",3);
+      par::prune_ld_win = getInt(s[0].c_str(),"--indep-pairwise");
+      par::prune_ld_step = getInt(s[1].c_str(),"--indep-pairwise");
+      par::prune_ld_r2 = getDouble(s[2].c_str(),"--indep-pairwise");
+      
+      if (par::prune_ld_win<2)
+        error("Cannot have a window size < 2 for --indep-pairwise {window} {step} {R^2}");
+      if (par::prune_ld_step<1)
+        error("Cannot have a window step < 1 for --indep-pairwise {window} {step} {R^2}");
+      if (par::prune_ld_r2<0)
+        error("Cannot have an R^2 threshold < 0 for --indep-pairwise {window} {step} {R^2}");
+      if (par::prune_ld_r2>1)
+        error("Cannot have an R^2 threshold > 1 for --indep-pairwise {window} {step} {R^2}");
+
+      // Compare to correlation
+      par::prune_ld_r2 = sqrt(par::prune_ld_r2);
+      
+    }
+  
+  if (a.find("--T2") || a.find("--t2") ) 
+    {
+      if ( a.find("--set-test") || a.find("--assoc") )
+	error("Cannot specify --T2 and other association commands");
+      par::set_test = true;
+      par::hotel = true;
+    }
+
+  if (a.find("--set")) {
+    par::setfile = a.value("--set");
+    
+  }
+
+  if (a.find("--set-test"))
+    {
+      par::set_test = true;
+      if ( (!a.find("--gene")) && ( a.find("--assoc") || a.find("--tdt") ) && 
+	   ( !a.find("--mperm") ) )
+	error("Must use --mperm N with set association tests");
+
+    }
+  
+  if (a.find("--set-score"))
+    {
+      par::set_test = true;
+      par::set_score = true;
+      par::set_score_p = a.value_double("--set-score");
+      par::set_max = par::set_min = 1;
+      if ( a.find("--set-min") || a.find("--set-max") )
+	error("Cannot specify --set-min or --set-max with --set-score");
+    }
+  
+  if (a.find("--set-p2"))
+    par::set_p2 = true;
+
+  if (a.find("--set-min"))
+    {
+      if (!a.find("--set"))
+	error ("You need to specify --set also");
+      par::set_min = a.value_int("--set-min");
+    }
+  
+  if (a.find("--set-max"))
+    {
+      if (!a.find("--set"))
+	error ("You need to specify --set also");
+      par::set_max = a.value_int("--set-max");
+    }
+  
+  //////////////////////////
+  // Impute tagged SNPs
+  
+  if (a.find("--hap-impute")) 
+    { 
+      par::impute_tags = true;
+      par::phase_snps = true;
+      //      par::hap_missing_geno = 1;
+    }
+
+  if (a.find("--hap-impute-verbose"))
+    {
+      par::impute_tags = true;    
+      par::phase_snps = true;
+
+      //      par::hap_missing_geno = 1;
+      par::impute_verbose = true;
+    }
+
+  if (a.find("--hap")) 
+    { 
+      par::phase_snps = true; 
+      par::tagfile = a.value("--hap"); 
+    }
+
+  if (a.find("--hap-window"))
+    {
+      par::phase_snps = true;
+      par::sliding_window = true;
+      par::phase_hap_all = true; 
+      if (a.find("--hap"))
+	error("Cannot specify both --hap-window and --hap {file}\n");
+      par::sliding_window_size = a.value_int("--hap-window");      
+
+      if (a.find("--hap-window-step"))
+	par::sliding_window_step = a.value_int("--hap-window-step");
+    }
+
+
+  // Using all SNPs, perform a basic sliding window analysis and look
+  // for haplotypically shared regions, i.e. given that we now have
+  // much more highly heterozygous markers
+
+  if (a.find("--homozyg-haplo-track"))
+    {
+      if ( ! a.find("--hap-window"))
+	error("The 'haplo-track' option requires --hap-window {s} to be specified");
+      
+      par::segment_haplotrack = true;
+      vector<string> s = a.value("--homozyg-haplo-track",2);
+      par::segment_haplotrack_fid1 = s[0];
+      par::segment_haplotrack_iid1 = s[1];
+      par::segment_haplotrack_fid2 = par::segment_haplotrack_fid1;
+      par::segment_haplotrack_iid2 = par::segment_haplotrack_iid1;      
+    }
+
+  if (a.find("--segment-haplo-track"))
+    {
+      if ( ! a.find("--hap-window"))
+	error("The 'haplo-track' option requires --hap-window {s} to be specified");
+
+      par::segment_haplotrack = true;
+      vector<string> s = a.value("--segment-haplo-track",4);
+      par::segment_haplotrack_fid1 = s[0];
+      par::segment_haplotrack_iid1 = s[1];
+      par::segment_haplotrack_fid2 = s[2];
+      par::segment_haplotrack_iid2 = s[3];
+    }
+
+
+
+  /////////////////////////////////
+  // EM Phasing options 
+
+  if (a.find("--em-verbose"))
+    par::haplo_plem_verbose = true;
+
+  if (a.find("--em-follow"))
+    {
+      par::haplo_plem_follow = true;
+      vector<string> s = a.value("--em-follow",2);
+      par::haplo_plem_follow_fid = s[0];
+      par::haplo_plem_follow_iid = s[1];
+    }
+
+  if (a.find("--em-window"))
+    par::haplo_plem_window = a.value_int("--em-window");
+
+  if (a.find("--em-overlap"))
+    par::haplo_plem_overlap = a.value_int("--em-overlap");
+
+  if (a.find("--em-window-iter"))
+    par::haplo_plem_iter = a.value_int("--em-window-iter");  
+
+  if (a.find("--em-window-prune-phase"))
+    par::haplo_plem_window_prune_phase = 
+      a.value_double("--em-window-prune-phase");
+
+  if (a.find("--em-window-likelihood"))
+    par::haplo_plem_likelihood_iter = a.value_int("--em-window-likilood");
+    
+  if (a.find("--em-window-tol"))
+    par::haplo_plem_window_tol = a.value_double("--em-window-tol");
+  
+  if (a.find("--em-window-prune-haplotype"))
+    {
+      par::haplo_plem_zero_threshold = a.value_double("--em-window-prune-haplotype");
+      if ( par::haplo_plem_zero_threshold == 0 )
+	par::haplo_plem_nonzero_threshold = false;
+      else
+	par::haplo_plem_nonzero_threshold = true;
+    }
+  
+
+
+  //////////////////////////
+  // Meta EM parameters
+
+  if (a.find("--em-meta-window"))
+    {
+      par::haplo_plem_meta_window = a.value_int("--em-meta-window");
+      if ( par::haplo_plem_meta_window < 2 )
+	error("--em-meta-window must be >1");
+    }
+  
+  if (a.find("--em-meta-prune-haplotype"))
+    par::haplo_plem_meta_prune_haplotype = 
+      a.value_double("--em-meta-prune-haplotype");
+
+  if (a.find("--em-meta-prune-phase"))
+    par::haplo_plem_meta_prune_phase = 
+      a.value_double("--em-meta-prune-phase");
+
+  if (a.find("--em-meta-iter"))
+    par::haplo_plem_meta_iter = a.value_int("--em-meta-iter");  
+
+  if (a.find("--em-meta-likilood"))
+    par::haplo_plem_meta_likelihood_iter = a.value_int("--em-meta-likilood");
+
+  if (a.find("--em-meta-tol"))
+    par::haplo_plem_meta_tol = a.value_double("--em-meta-tol");
+  
+
+  /////////////////////////////
+  // Other haplotype options
+
+  if (a.find("--hap-all")) 
+    { 
+      if (!a.find("--hap"))
+	error("--hap-all modifies --hap, but you have not specified --hap");
+      par::phase_hap_all = true; 
+    }
+  
+  if (a.find("--whap")) 
+    { 
+      par::phase_snps = true; 
+      par::tagfile = a.value("--whap"); 
+      par::weighted_mm = true;
+    }
+
+  if (a.find("--hap-pp")) { par::hap_post_prob = a.value_double("--hap-pp"); }
+  if (a.find("--hap-miss")) { par::hap_missing_geno = a.value_double("--hap-miss"); }
+  
+  if (a.find("--hap-freq")) 
+    { 
+      if ( par::impute_tags ) 
+	error("Cannot specify --hap-impute and --hap-freq\n");
+      par::display_hap_freqs = true;     
+    }
+
+  if (a.find("--hap-assoc")) 
+    { 
+      if ( par::impute_tags ) 
+	error("Cannot specify --hap-impute and --hap-assoc\n");
+      par::test_hap_CC = true; 
+    }
+  
+  if (a.find("--chap"))
+    {
+      if ( ! a.find("--hap-snps"))
+	error("--chap requires --hap-snps");
+
+      par::chap_test = true;
+
+      if ( a.find("--null-group") )
+	{
+	  par::chap_specified_groups = true;
+	  par::chap_model0 = a.value("--null-group");
+	}
+      
+      if ( a.find("--alt-group") )
+	{
+	  par::chap_specified_groups = true;
+	  par::chap_model1 = a.value("--alt-group");
+	}
+
+      if ( a.find("--null-snp") )
+	{
+	  if ( par::chap_specified_groups )
+	    error("Cannot specify SNPs and groups for --chap tests");
+	  par::chap_specified_snps = true;
+	  par::chap_model0 = a.value("--null-snp");
+	}
+
+      if ( a.find("--alt-snp") )
+	{
+	  if ( par::chap_specified_groups )
+	    error("Cannot specify SNPs and groups for --chap tests");
+	  par::chap_specified_snps = true;
+	  par::chap_model1 = a.value("--alt-snp");
+	}
+
+      if ( a.find("--control") )
+	{
+	  if ( par::chap_specified_groups ||
+	       par::chap_specified_snps )
+	    error("Cannot use --control and other --chap options");
+	  par::chap_sole_variant = true;
+	  par::chap_entity = a.value("--control");
+	}
+      else if ( a.find("--independent-effect") )
+	{
+	  if ( par::chap_specified_groups ||
+	       par::chap_specified_snps )
+	    error("Cannot use --independent-effect and other --chap options");
+	  par::chap_independent_effect = true;
+	  par::chap_entity = a.value("--independent-effect");
+	}      
+      else if ( a.find("--specific-haplotype") )
+	{
+	  if ( par::chap_specified_groups ||
+	       par::chap_specified_snps )
+	    error("Cannot use --specific-haplotype and other --chap options");
+	  par::chap_haplotype_specific = true;
+	  par::chap_entity = a.value("--specific-haplotype");	  
+	}
+
+      if ( a.find("--test-snp") )
+	{
+	  if ( ! ( a.find("--condition") || a.find("--condition-list") ) )
+	    error("You must first specify conditioning SNPs");
+	  par::chap_drop_snps = true;
+	  par::chap_drop_snps_list = a.value("--test-snp");
+	}
+
+      if ( a.find("--each-vs-others") )
+	par::chap_add_grp_specifics = true;
+
+      if ( a.find("--each-versus-others") )
+	par::chap_add_grp_specifics = true;
+
+    }
+
+  
+  if (a.find("--hap-snps"))
+    {
+      if ( a.find("--hap") || a.find("--hap-window"))
+	error("Cannot specify --hap-snps with --hap or --hap-window");
+      par::phase_snps = true;
+      par::hap_specific_snps = true;
+      par::hap_specific_snps_list = a.value("--hap-snps");
+      par::phase_hap_all = true; 
+    }
+  
+  if (a.find("--hap-tdt")) 
+    { 
+      if ( par::impute_tags ) 
+	error("Cannot specify --hap-impute and --hap-tdt\n");
+      par::test_hap_TDT = true; 
+    }
+  
+  if (a.find("--hap-phase")) 
+    { 
+      if ( par::impute_tags ) 
+	error("Cannot specify --hap-impute and --hap-phase\n");
+      par::display_phase_probs = true;
+    }
+  
+  if (a.find("--hap-phase-wide")) 
+    { 
+      if ( par::impute_tags ) 
+	error("Cannot specify --hap-impute and --hap-phase-wide\n");
+      par::display_phase_probs = par::display_phase_probs_wide = true; 
+    }
+  
+  if (a.find("--hap-only")) { par::test_hap_only = true; } 
+  
+  if (a.find("--hap-max-phase")) 
+    { 
+      par::hap_max_nf_phases = a.value_int("--hap-max-phase"); 
+      if ( par::hap_max_nf_phases < 1 ) error("Invalid --hap-max-phase value (should be >0)");
+    }
+  
+  if (a.find("--hap-min-phase-prob")) 
+    { 
+      par::hap_min_phase_prob = a.value_double("--hap-min-phase-prob"); 
+      if ( par::hap_min_phase_prob < 0 || par::hap_min_phase_prob > 1 ) 
+	error("Invalid --hap-min-phase-prob value, should be between 0 and 1");
+    }
+  
+
+
+
+  //////////////////////////
+  // Epistasis
+
+  if (a.find("--epistasis")) 
+    {
+      if (a.find("--set"))
+	par::set_test = true;
+      par::epistasis = true;
+    }
+
+  // Use odds-ratio test as default fast-epistasis method
+  if (a.find("--fast-epistasis")) 
+    { 
+      par::fast_epistasis = par::epistasis = true; 
+      if ( a.find("--set"))
+	par::set_test = true;
+    }
+
+  if (a.find("--case-only")) 
+    { 
+      par::epistasis = true; 
+      par::fast_epistasis = true;
+      par::epi_caseonly = true; 
+      if (a.find("--epistasis"))
+	error("--case-only requires --fast-epistasis");
+    } 
+
+  if (a.find("--gap")) 
+    { 
+      if (!a.find("--case-only")) error("--gap option only valid when --caseonly is in effect");
+      par::epi_caseonly_kb_gap = a.value_double("--gap"); 
+    }
+  if (a.find("--nop")) par::epi_quickscan = true;
+  if (a.find("--set-by-all")) par::set_by_set = false;
+  if (a.find("--epi1")) par::epi_alpha1 = a.value_double("--epi1");
+  if (par::epi_alpha1 > 1) par::epi_filter = false;
+  if (a.find("--epi2")) par::epi_alpha2 = a.value_double("--epi2");
+  if (a.find("--twolocus"))
+    {
+      par::list_twolocus = true;
+      vector<string> s = a.value("--twolocus",2);
+      par::twolocus_snp1 = s[0];
+      par::twolocus_snp2 = s[1];      
+    }
+  
+  if (a.find("--genepi")) 
+    {
+      par::set_test = true;
+      par::epi_genebased = true;
+    }
+
+
+  
+  ///////////////////////////////////////
+  // Gene X environment / heterogeneity
+  
+
+
+
+  //////////////////////////////////////
+  // File output options
+
+  if (a.find("--freq")) 
+    {
+      par::af_write = true;
+      // and unless otherwise specified, set GENO = 1 and MAF = 0
+//       if (!a.find("--maf")) par::min_af = 0.0;
+//       if (!a.find("--geno")) par::MAX_GENO_MISSING = 1;
+//       if (!a.find("--mind")) par::MAX_IND_MISSING = 1;
+
+      // display MAF counts instead of freqs?
+      if (a.find("--counts"))
+	{
+	  if (a.find("--within"))
+	    error("Cannot specify --counts and --within together\n");
+	  par::af_count = true;
+	}
+   }  
+
+
+  
+  if (a.find("--nonfounders")) par::summ_nonfounders = true;
+
+  if (a.find("--make-founders")) par::make_founders = true;
+
+  if (a.find("--allow-no-sex")) par::ignore_missing_sex = true;
+  
+  if (a.find("--read-freq")) 
+    {
+      par::af_read = true;
+      par::af_file = a.value("--read-freq");
+    }
+
+  if (a.find("--read-genome")) 
+    {
+      par::ibd_read = true;
+      par::ibd_file = a.value("--read-genome");
+    }
+
+  if (a.find("--list")) 
+    {
+      par::list_by_allele = true;
+      // and unless otherwise specified, set GENO = 1 and MAF = 0
+      if (!a.find("--maf")) par::min_af = 0.0;
+      if (!a.find("--geno")) par::MAX_GENO_MISSING = 1;     
+      if (!a.find("--mind")) par::MAX_IND_MISSING = 1;
+    }
+  
+  if (a.find("--report"))
+    {
+      par::indiv_report = true;
+      vector<string> s = a.value("--report",2);
+      par::indiv_report_fid = s[0];
+      par::indiv_report_iid = s[1];
+      if (!a.find("--maf")) par::min_af = 0.0;
+      if (!a.find("--geno")) par::MAX_GENO_MISSING = 1;     
+      if (!a.find("--mind")) par::MAX_IND_MISSING = 1;
+    }
+
+  if (a.find("--plist")) 
+    {
+      par::plist = true;
+      // and unless otherwise specified, set GENO = 1 and MAF = 0
+      if (!a.find("--maf")) par::min_af = 0.0;
+      if (!a.find("--geno")) par::MAX_GENO_MISSING = 1;     
+      if (!a.find("--mind")) par::MAX_IND_MISSING = 1;
+
+      vector<string> s = a.value("--plist",4);
+      par::plist_fid1 = s[0];
+      par::plist_iid1 = s[1];
+      par::plist_fid2 = s[2];
+      par::plist_iid2 = s[3];
+      
+    }
+
+
+  if (a.find("--fix-allele"))
+    {
+      if (! (a.find("--recodeAD") || a.find("--recodeA")) )
+	error("--fix-allele option only works with --recodeA/--recodeAD options");
+      else par::recode_AD_fixed = true;
+    }
+
+  if (a.find("--merge"))
+    {
+      if (a.find("--merge-list") || a.find("--bmerge") )
+	error("Can only specify --merge or --bmerge or --merge-list");
+
+      par::merge_data = true;
+      vector<string> s = a.value("--merge",2);
+      par::merge_pedfile = s[0];
+      par::merge_mapfile = s[1];
+    }
+
+  if (a.find("--bmerge"))
+    {
+      if (a.find("--merge-list") || a.find("--merge") )
+	error("Can only specify --bmerge or --merge or --merge-list");
+
+      par::merge_data = true;
+      par::merge_binary = true;
+
+      vector<string> s = a.value("--bmerge",3);
+      par::merge_bedfile = s[0];
+      par::merge_bimfile = s[1];
+      par::merge_famfile = s[2];
+
+    }
+
+  if (a.find("--merge-list"))
+    {
+      if (a.find("--merge") || a.find("--bmerge") )
+	error("Can only specify --merge or --bmerge or --merge-list");
+      
+      par::merge_data = true;
+      par::merge_list = true;
+      par::merge_list_filename = a.value("--merge-list");
+    }
+
+  if (a.find("--merge-mode"))
+    {
+      if (! (a.find("--merge") || a.find("--merge-list") || a.find("--bmerge") ) )
+	error("Can only specify --merge-mode when --merge or --bmerge or --merge-list is used");
+      par::merge_mode = a.value_int("--merge-mode");
+      if (par::merge_mode < 1 || par::merge_mode > 7)
+	error("--merge-mode N, where N must be between 1 and 7"); 
+      
+      if (par::merge_list && par::merge_mode >= 6)
+	error("Can not specify --merge-mode 6/7 (diff) and --merge-list");
+    }
+
+
+  if (a.find("--flip")) 
+    {
+      par::flip_strand = true;     
+      par::flip_file = a.value("--flip");
+    }
+
+  // Remove these individuals from a file
+  if (a.find("--remove")) 
+    { 
+      par::remove_indiv = true; 
+      par::remove_indiv_list = a.value("--remove");
+    }
+
+  // Keep only these individuals from a file 
+  if (a.find("--keep")) 
+    { 
+      par::keep_indiv = true;
+      par::keep_indiv_list = a.value("--keep");
+    }
+  
+  // By default, remove then keep
+  if (a.find("--keep-before-remove"))
+    par::remove_before_keep = false;
+
+  // Extract only these SNPs from a file
+  if (a.find("--extract")) 
+    { 
+      par::extract_set = true; 
+      par::extract_file = a.value("--extract");
+    }
+
+  // Exclude these SNPs from a file
+  if (a.find("--exclude")) 
+    { 
+      par::exclude_set = true; 
+      par::exclude_file = a.value("--exclude");
+    }
+  
+  // Select a set of SNPs based on different physical 
+  // positions: this modifies the behavior of --extract 
+  // and --exclude
+
+  if (a.find("--range"))
+    {
+      if ( ! ( a.find("--extract") || a.find("--exclude") ) )
+	error("Must specify --extract or --exclude with --range");
+      par::snp_range_list = true;
+    }
+
+  // By default, extract before exclude
+  if (a.find("--exclude-before-extract"))
+    par::extract_before_exclude = false;
+  
+
+  // Extract SNPs in a certain GENE (specified in the SET file)
+  if (a.find("--gene"))
+    {
+      if (!a.find("--set"))
+	error("You must also specify --set {file} with --gene {gene}\n");
+      par::extract_set = true;
+      par::dump_gene = true;
+      par::dump_genename = a.value("--gene");
+    }
+
+
+  if (a.find("--ind-major"))
+    {
+      if (!a.find("--make-bed"))
+	error("You can only specify --ind-major when --make-bed is in effect");
+      par::out_SNP_major = false;
+    }
+
+  
+  if (a.find("--include")) par::inc_write = true;
+  
+  if (a.find("--read-include")) 
+    {
+      par::inc_read = true;
+      par::inc_file = a.value("--read-include");
+    }
+
+
+  ///////////////////////////
+  // Plink phenotype definition
+//   // Squared differences (quantitative trait)
+//   if (a.find("--SD")) { par::SD = true; par::CP = false; }
+//   // Cross-product (quantitative trait)
+//   if (a.find("--CP")) { par::CP = true; par::SD = false; } 
+//   // Fix the prevalence of a binary trait
+//   if (a.find("--prev")) {
+//     par::fix_prev=true; 
+//     par::fixed_prev = a.value_double("--prev"); 
+//   }
+//   // Remove unaffected pairs from analysis 
+//   // i.e. so only discordant versus affected concordant
+//   // i.e. need at least 1 affected "1A"
+//   if (a.find("--1aff")) { par::remove_unaffected_pairs = true; }
+
+
+
+  ///////////////////////////
+  // Some basic filters
+
+  if (a.find("--prune")) 
+    par::ignore_phenotypes = false;  
+  if (a.find("--filter-cases"))
+    par::filter_cases = true;
+  if (a.find("--filter-controls"))
+    par::filter_controls = true;
+  if (a.find("--filter-females"))
+    par::filter_females = true;
+  if (a.find("--filter-males"))
+    par::filter_males = true;
+  if (a.find("--filter-founders"))
+    par::filter_founders = true;
+  if (a.find("--filter-nonfounders"))
+    par::filter_nonfounders = true;
+
+  if (a.find("--filter-cases") && a.find("--filter-controls"))
+    error("Cannot filter on both cases and controls");
+  if (a.find("--filter-males") && a.find("--filter-females"))
+    error("Cannot filter on both males and females");
+  if (a.find("--filter-founders") && a.find("--filter-nonfounders"))
+    error("Cannot filter on both founders and nonfounders");
+
+
+  /////////////////////////////////
+  // Basic input file processing 
+  
+  if (a.find("--dummy"))
+    {
+      vector<string> s = a.value("--dummy",2);      
+      par::dummy = true;
+      par::dummy_nind = getInt(s[0].c_str(),"--dummy");
+      par::dummy_nsnp = getInt(s[1].c_str(),"--dummy");
+    }  
+  
+  if (a.find("--simulate"))
+    {
+      par::simul = true;
+      par::simul_file = a.value("--simulate");
+    }
+  
+  if (a.find("--simulate-ncases"))
+    par::simul_ncases = a.value_int("--simulate-ncases");
+
+  if (a.find("--simulate-ncontrols"))
+    par::simul_ncontrols = a.value_int("--simulate-ncontrols");
+
+  if (a.find("--simulate-prevalence"))
+    par::simul_prevalence = a.value_double("--simulate-prevalence");
+
+  if (a.find("--file")) 
+    { 
+      if (a.find("--map") || a.find("--ped") ) 
+	error("Use either --file {root} OR --ped {name} --map {name}");
+      par::read_ped = true;
+      par::fileroot = a.value("--file");
+      par::pedfile = par::fileroot + ".ped";
+      par::mapfile = par::fileroot + ".map";
+    }
+
+
+  if (a.find("--tfile")) 
+    { 
+      if (a.find("--tfam") || a.find("--tped") ) 
+	error("Use either --tfile {root} OR --tped {name} --tfam {name}");
+
+      par::tfile_input = true;
+      par::fileroot = a.value("--tfile");
+      par::tpedfile = par::fileroot + ".tped";
+      par::tfamfile = par::fileroot + ".tfam";
+    }
+
+  if (a.find("--tped")) 
+    {
+      par::tpedfile = a.value("--tped");
+      if (par::tpedfile == "-")
+	  par::ped_from_stdin = true;
+      par::tfile_input = true;
+    }
+  
+  if (a.find("--tfam")) 
+    {
+      par::tfamfile = a.value("--tfam");
+      par::tfile_input = true;
+    }
+      
+  // Long file format
+
+  if (a.find("--lfile")) 
+    { 
+      if (a.find("--fam") || a.find("--lgen") || a.find("--map") )  
+	error("Use either --lfile {root} OR --lgen {name} --map (name) --fam {name}");
+
+      par::lfile_input = true;
+      par::fileroot = a.value("--lfile");
+      par::lpedfile = par::fileroot + ".lgen";
+      par::lfamfile = par::fileroot + ".fam";
+      par::mapfile = par::fileroot + ".map";
+    }
+
+  if (a.find("--lgen")) 
+    {
+      par::lpedfile = a.value("--lgen");
+      if (par::lpedfile == "-")
+	  par::ped_from_stdin = true;
+      par::lfile_input = true;
+    }
+
+
+  /////////////////////
+  // Generic variant 
+
+  if (a.find("--gfile"))
+    {
+      // Analyse generic variants
+      par::gvar = true;
+      // Primarily load these; this will be changed
+      // if another load is not specified
+      par::load_gvar = false;
+      par::fileroot = a.value("--gfile");
+      par::gmapfile = par::fileroot + ".map";
+      par::gfamfile = par::fileroot + ".fam";
+      
+      if (a.find("--gvar-verbose"))
+	par::gvar_verbose_association = true;
+
+      if (a.find("--gvar-all"))
+	par::gvar_include_all_variants = true;
+    }
+  
+  // Text-file modifiers
+
+  if (a.find("--map3"))
+    par::map3 = true;
+
+  if (a.find("--no-sex"))
+    par::ped_skip_sex = true;
+
+  if (a.find("--no-parents"))
+    par::ped_skip_parents = true;
+
+  if (a.find("--no-fid"))
+    par::ped_skip_fid = true;
+  
+  if (a.find("--no-pheno"))
+    par::ped_skip_pheno = true;
+
+  if (a.find("--liability"))
+    par::liability = true;
+      
+  if (a.find("--bfile")) 
+    { 
+      if (a.find("--bim") || a.find("--bed") || a.find("--fam") ) 
+	error("Use either --bfile {root} OR --bed {name} --bim {name} --fam {name}");
+      
+      par::read_bitfile = true;
+      par::fileroot = a.value("--bfile");
+      par::bitfilename = par::pedfile = par::fileroot + ".bed";
+      par::bitfilename_map = par::mapfile = par::fileroot + ".bim";
+      par::bitfilename_fam = par::fileroot + ".fam";
+    }
+
+  if (a.find("--bfile-faster"))
+    par::fast_binary = true;
+  
+  if (a.find("--ped")) 
+      {
+	par::read_ped = true;
+	par::pedfile = a.value("--ped");
+	if (par::pedfile == "-")
+	  par::ped_from_stdin = true;
+      }
+  
+  if (a.find("--map")) par::mapfile = a.value("--map");
+    
+
+  if (a.find("--bed"))
+    {
+      par::read_bitfile = true;
+      par::bitfilename = par::pedfile = a.value("--bed");
+    }
+  
+  if (a.find("--fam"))
+  {
+    par::read_bitfile = true;
+    par::bitfilename_fam = a.value("--fam");
+  }
+  
+  if (a.find("--bim"))
+  {
+    par::read_bitfile = true;
+    par::bitfilename_map = par::mapfile = a.value("--bim");
+  }
+  
+
+  // Single phenotype in file specified
+  if (a.find("--pheno")) 
+    {
+      par::pheno_file = true;
+      par::pheno_filename = a.value("--pheno");
+    }
+
+  // Binary 0/1 coding instead of 1/2
+  if (a.find("--1"))
+    par::coding01 = true;
+
+
+  // Multiple phenotypes in a file specified
+  if (a.find("--mpheno")) 
+    {
+      if (!a.find("--pheno"))
+	error("You need to specify --pheno {file} with --mpheno {N}");
+      par::mult_pheno = a.value_int("--mpheno");
+    }
+
+  // Select phenotype ny name
+  if (a.find("--pheno-name")) 
+    {
+      if (!a.find("--pheno"))
+	error("You need to specify --pheno {file} with --pheno-name {name}");
+      if (a.find("--mpheno"))
+	error("You cannot specify --mpheno and --pheno-name together");
+
+      par::name_pheno = a.value("--pheno-name");
+      
+    }
+
+  if (a.find("--values"))
+    {
+      par::number_list_string = a.value("--values");
+    }
+
+  if (a.find("--valueless"))
+    {
+      par::number_list_string = a.value("--valueless");
+      par::number_list_positive = false;
+    }
+
+  // Loop over all phenotypes
+  if (a.find("--all-pheno")) 
+    {
+      if (!a.find("--pheno"))
+	error("You need to specify --pheno {file} with --all-pheno");
+      
+      if (a.find("--mpheno"))
+	error("You cannot specify --mpheno {N} with --all-pheno");
+      par::mult_pheno = 1;
+      par::all_pheno = true;
+
+    }
+
+  
+  // Single covariate in file specified
+  if (a.find("--covar")) 
+    { 
+      par::covar_file = true;
+      par::covar_filename = a.value("--covar");
+      
+      // Multiple covariates in file specified, read all of them
+      if ( a.find("--linear") || 
+	   a.find("--logistic") || 
+	   a.find("--R") || 
+	   a.find("--chap") || 
+	   a.find("--proxy-glm") )
+	par::clist = true;
+      
+      // Request to dump back out all covariates
+      if (makedata)
+	{
+	  par::clist = true;
+	  if (a.find("--dummy-coding"))
+	    par::dump_covar_dummy_coding = true;
+	}
+
+      if (a.find("--with-phenotype"))
+	par::dump_covar_with_phenotype = true;
+ 
+    }
+  
+
+  // Multiple covariates in file specified, select one
+  if (a.find("--mcovar")) 
+    {
+      if (!a.find("--covar"))
+	error("You need to specify --covar {file} with --mcovar {N}");
+      par::mult_covar = a.value_int("--mcovar");
+    }
+
+  // Selection fields for covariates
+  if (a.find("--covar-number"))
+    {
+      par::clist_selection = par::clist_selection_number = true;
+      par::clist_selection_string = a.value("--covar-number");
+    }
+  
+  if ( a.find("--covar-name") )
+    {
+      par::clist_selection = par::clist_selection_name = true;
+      par::clist_selection_string = a.value("--covar-name");
+    }
+    
+  // Request to dump back out all covariates
+  if (a.find("--write-covar"))
+  {
+    if (makedata)
+      error("No need to specify --write-covar separately");
+    if (!a.find("--covar")) 
+      error("You must specify a --covar {file} with --write-covar");
+
+    if (a.find("--with-phenotype"))
+      par::dump_covar_with_phenotype = true;
+
+    if (a.find("--dummy-coding"))
+      par::dump_covar_dummy_coding = true;
+    
+    par::dump_covar = true;
+    par::clist = true;
+  }
+  
+  if (a.find("--write-snplist"))
+    par::write_snplist = true;
+
+  if (a.find("--update-map"))
+    {
+      if (a.find("--update-cm"))
+	par::update_cm = true;
+      par::update_map = true;
+      par::update_mapfile = a.value("--update-map");
+    }
+
+  // Examine only a subset of the data?
+  if (a.find("--filter"))
+    {
+      par::filter_on_covar = true;
+
+      vector<string> s = a.value("--filter",2);
+      
+      par::filter_filename  = s[0];
+      par::filter_value = getInt(s[1].c_str(),"--filter");
+           
+    }
+  
+  if (a.find("--mfilter"))
+    {
+      if (!a.find("--filter"))
+	error("You can only specify --mfilter with --filter\n");
+      par::mult_filter = a.value_int("--mfilter");
+    }
+  
+  // Different species other than human?
+  // i.e. alters chromosome definitions
+  
+  if (a.find("--dog")) par::species_dog = true;
+  if (a.find("--cow")) par::species_cow = true;
+  if (a.find("--sheep")) par::species_sheep = true;
+  if (a.find("--horse")) par::species_horse = true;
+
+  //////////////////////////////////
+  // Multipoint and singlepoint 
+
+  //  if (a.find("--singlepoint")) par::singlepoint = true; 
+
+  if (a.find("--fringe")) 
+    {
+      par::singlepoint = false;
+      par::fringe = a.value_double("--fringe");
+    }  
+
+  if (a.find("--grid")) 
+    {
+      par::singlepoint = false;
+      par::grid = a.value_double("--grid");
+      par::inter_grid = 0;
+    }
+
+  if (a.find("--step")) 
+    {
+      par::singlepoint = false;
+      par::inter_grid = a.value_int("--step");
+    }
+
+  if (a.find("--cm")) par::cm_map = true;
+    
+  if (a.find("--ci")) 
+    {
+      par::display_ci = true;
+      par::ci_level = a.value_double("--ci");
+      if ( par::ci_level < 0.01 || par::ci_level >= 1 )
+	error("CI level (--ci) must be between 0 and 1\n");
+      par::ci_zt = ltqnorm( 1 - (1 - par::ci_level) / 2  );
+    }
+
+  if (a.find("--pfilter")) 
+    {
+      par::pfilter = true;
+      par::pfvalue = a.value_double("--pfilter");
+    }
+
+  if (a.find("--clump"))
+    {
+      par::clumpld = true;
+      par::clumpld_results = a.value("--clump");
+      
+      if (a.find("--clump-field"))
+	par::clumpld_column = a.value("--clump-field");      
+
+      if (a.find("--clump-verbose"))
+	par::clumpld_verbose = true;
+      
+      if (a.find("--clump-p1"))
+	par::clumpld_p1 = a.value_double("--clump-p1");
+
+      if (a.find("--clump-p2"))
+	par::clumpld_p2 = a.value_double("--clump-p2");
+
+      if (a.find("--clump-r2"))
+	par::clumpld_r2 = a.value_double("--clump-r2");
+
+      if (a.find("--clump-kb"))
+	par::clumpld_kb = a.value_int("--clump-kb") * 1000;
+
+      if (a.find("--clump-index-first"))
+	par::clumpld_index1 = true;
+
+      if (a.find("--clump-replicate"))
+	par::clumpld_only_show_replications = true;
+
+      if (a.find("--clump-annotate"))
+	{
+	  par::clumpld_annot = true;
+	  par::clumpld_annot_fields = a.value("--clump-annotate");
+	}
+      
+      if (a.find("--clump-allow-overlap"))
+        par::clumpld_indep = false;
+
+    }
+
+
+  if (a.find("--adjust")) 
+    { par::multtest = true; }
+
+  if (a.find("--log10")) 
+    { par::logscale = true; }
+
+  if (a.find("--qq-plot")) 
+    { par::qq_plot = true; }
+
+  if (a.find("--lambda"))
+    {
+      par::fix_lambda = true;
+      par::lambda = a.value_double("--lambda");
+      if ( par::lambda < 1 ) 
+	par::lambda = 1;
+    }
+
+  if (a.find("--gc"))
+    {
+      if (!a.find("--adjust"))
+	error("Must specify --adjust to use --gc");
+      par::use_GC = true;
+    }
+
+  ///////////////////////
+  // Permutation options
+
+
+
+  // Use permutations (default is adaptive)
+  if (a.find("--perm"))
+    {
+      par::permute = true;
+    }
+
+  // Return counts not p-values (i.e. number of times exceeded)
+  if ( a.find("--perm-count") )
+    {
+      par::perm_count = true;
+    }
+
+  // Specify parameters for adaptive permutation
+  if (a.find("--aperm"))
+    {
+      if (a.find("--segment"))
+	error("--segment options requires --pperm option");
+      
+      if (a.find("--set"))
+	error("Cannot use --aperm with --set option (use --mperm N instead)");
+      
+      par::permute = true;
+      par::adaptive_perm = true;
+      vector<string> s = a.value("--aperm",6);
+
+      par::adaptive_min       = getInt(s[0].c_str(),"--aperm");
+      par::adaptive_max       = getInt(s[1].c_str(),"--aperm");
+      par::adaptive_alpha     = getDouble(s[2].c_str(),"--aperm");
+      par::adaptive_ci        = getDouble(s[3].c_str(),"--aperm");
+      par::adaptive_interval  = getInt(s[4].c_str(),"--aperm");
+      par::adaptive_interval2 = getDouble(s[5].c_str(),"--aperm");
+    }
+
+
+  // Non-adaptive (maxT) permutations
+  if (a.find("--mperm")) 
+    {
+      par::permute = true;
+      par::adaptive_perm = false;
+      par::replicates = a.value_int("--mperm");
+
+      if (a.find("--mperm-save"))
+	par::mperm_save_best = true;
+      else if (a.find("--mperm-save-all"))
+	par::mperm_save_all = true;
+
+
+      // But make special fix for QFAM tests
+      if ( par::QTDT_test )
+	{
+	  par::adaptive_perm = true;
+	  par::adaptive_min       = par::replicates;
+	  par::adaptive_max       = par::replicates;
+	  par::adaptive_alpha     = 0;
+	  par::adaptive_ci        = 0;
+	  par::adaptive_interval  = par::replicates+1;
+	  par::adaptive_interval2 = 0;
+	  par::QFAM_adaptive = true;
+	}
+    }
+
+
+  if (a.find("--rank"))
+    {
+      if (! a.find("--mperm") )
+	error("--rank requires --mperm to be specified");
+      par::mperm_rank = true;
+    }
+
+  // PLINK permutations
+
+  if (a.find("--pperm")) 
+    {
+      if (! ( a.find("--segment") || a.find("--read-segment") ) )
+	error("--pperm options requires --segment or --read-segment option");
+      par::permute = true;
+      par::adaptive_perm = false;
+      par::replicates = a.value_int("--pperm");
+    }
+
+
+  if (a.find("--p2"))
+    {
+      if ((!a.find("--perm")) 
+	  && (!a.find("--mperm"))
+	  && (!a.find("--aperm")))
+	error("--p2 option also requires--perm, --aperm or --mperm"); 
+      else if (!a.find("--assoc"))
+	error("The --p2 option can only be specified with --assoc");
+      else par::assoc_test_alt_perm = true;
+    }
+
+
+  /////////////////////
+  // Gene-dropping
+
+  if (a.find("--genedrop")) 
+    par::perm_genedrop = par::permute = true;
+
+  if (a.find("--swap-sibs")) 
+    {
+      if (!a.find("--genedrop"))
+	error("--swap-sibs only makes sense when --genedrop specified");
+      par::perm_genedrop_sibships = true;      
+      par::perm_genedrop_and_swap = true;
+    }
+
+  if (a.find("--swap-parents")) 
+    {
+      if (!a.find("--genedrop"))
+	error("--swap-parents only makes sense when --genedrop specified");
+      par::perm_genedrop_parents = true;      
+      par::perm_genedrop_and_swap = true;
+    }
+
+  if (a.find("--swap-unrel")) 
+    {
+      if (!a.find("--genedrop"))
+	error("--swap-unrel only makes sense when --genedrop specified");
+
+      par::perm_genedrop_unrel = true;
+      par::perm_genedrop_and_swap = true;
+    }
+
+
+  ///////////////////////
+  // Misc. options
+
+  if (a.find("--missing-genotype")) 
+    par::missing_genotype = a.value("--missing-genotype");
+
+  if (a.find("--missing-phenotype")) 
+    par::missing_phenotype = a.value("--missing-phenotype");
+
+  if (a.find("--FIX")) {
+    par::FIXED = par::FIXED_p = true;
+    vector<string> p = a.value("--FIX",4);
+    
+    par::FIX_IBD.z0 = getDouble(p[0].c_str(),"--FIX");
+    par::FIX_IBD.z1 = getDouble(p[1].c_str(),"--FIX");
+    par::FIX_IBD.z2 = getDouble(p[2].c_str(),"--FIX");
+    par::FIX_p = getDouble(p[3].c_str(),"--FIX");
+    cout << "Fixing Z0, Z1, Z2 and p to " 
+	 << par::FIX_IBD.z0 << " "
+	 << par::FIX_IBD.z1 << " "
+	 << par::FIX_IBD.z2 << " "
+	 << par::FIX_p << "\n(p must refer to '1' allele in '1/2' genotype)\n";
+  }
+
+
+  if (a.find("--fix-ibd")) {
+    par::FIXED = true;
+    vector<string> p = a.value("--fix-ibd",3);
+    
+    par::FIX_IBD.z0 = getDouble(p[0].c_str(),"--fix-ibd");
+    par::FIX_IBD.z1 = getDouble(p[1].c_str(),"--fix-ibd");
+    par::FIX_IBD.z2 = getDouble(p[2].c_str(),"--fib-ibd");
+
+  }
+
+
+  if (a.find("--batch")) 
+    par::BATCH_SIZE = a.value_int("--batch");
+
+  if (a.find("--min")) 
+    par::MIN_PIHAT = a.value_double("--min"); 
+  
+  if (a.find("--max")) 
+    par::MAX_PIHAT = a.value_double("--max"); 
+  
+  if (a.find("--all-pairs"))
+    {
+      if (a.find("--min"))
+	error("Cannot specify --min and --all-pairs\n");      
+      par::include_all_pairs = true;      
+    }
+
+
+//   if (a.find("--lock"))
+//     { par::locked = true; }
+  
+//   if (a.find("--unlock"))
+//     { par::locked = false; }
+
+
+  ///////////////////////////////
+  // Basic filters
+  
+  if (a.find("--all"))
+    {
+      par::min_af = 0.0;
+      par::MAX_GENO_MISSING = 1;
+      par::MAX_IND_MISSING = 1;
+    }
+ 
+  if (a.find("--geno")) 
+    par::MAX_GENO_MISSING = a.value_double("--geno"); 
+
+  if (a.find("--mind")) 
+    par::MAX_IND_MISSING = a.value_double("--mind"); 
+
+  if (a.find("--maf")) 
+    par::min_af = a.value_double("--maf");
+
+  if (a.find("--max-maf")) 
+    {
+      par::max_af = a.value_double("--max-maf");
+      if (par::max_af < par::min_af)
+	error("Cannot set --max-maf less than --maf\n");
+    }
+
+  if (a.find("--mhf"))
+    par::min_hf = a.value_double("--mhf");
+  
+  if (a.find("--max-mhf"))
+    {
+      par::max_hf = a.value_double("--max-mhf");
+      if (par::max_hf < par::min_hf)
+	error("Cannot set --max-mhf less than --mhf\n");
+    }
+
+  if (a.find("--hwe")) 
+    {
+      par::HWD_test = true;
+      par::HWD_limit = a.value_double("--hwe");
+    }
+
+  if (a.find("--hwe2")) 
+    {
+      par::HWD_test = true;
+      par::HWD_standard = true;
+      par::HWD_limit = a.value_double("--hwe2");
+    }
+
+  if (a.find("--hwe-all")) 
+    {
+      par::HWD_filter_on_all = true;
+    }
+
+
+  if (a.find("--me")) 
+    {
+      par::MENDEL_test = true;
+      vector<string> s = a.value("--me",2);
+      par::MENDEL_ind = getDouble(s[0],"--me");
+      par::MENDEL_snp = getDouble(s[1],"--me");
+    }
+
+
+
+  //////////////////////////////////
+  // IBS clustering
+
+  if (a.find("--cluster")) 
+    {
+
+      par::cluster = true;
+
+      if (a.find("--within"))
+	par::force_initial_cluster = true;
+
+    }
+
+  if (a.find("--euclidean")) 
+    {
+      if (!a.find("--cluster"))
+	error("Cannot specify --euclidean without --cluster");
+      par::cluster_euclidean = true;
+    }
+
+
+
+  if (a.find("--pick1")) 
+    {
+      par::cluster_selcon = true;
+      par::cluster_selcon_file = a.value("--pick1");
+    }
+
+  if (a.find("--cluster-missing")) 
+    {
+      par::cluster = true;
+      par::cluster_missing = true;
+      par::matrix = true;
+      
+      if (!a.find("--maf")) par::min_af = 0.0;
+      if (!a.find("--geno")) par::MAX_GENO_MISSING = 1;
+      if (!a.find("--mind")) par::MAX_IND_MISSING = 1;
+ 
+      par::merge_p = 0;
+      if (a.find("--ppc"))
+	error("Cannot specify --ppc with --cluster-missing");
+    }
+
+  if (a.find("--K")) 
+    {
+      if (!a.find("--cluster"))
+	error("Must specify --cluster also if --K used");
+      par::max_cluster_N = a.value_int("--K");     
+    }
+  
+  if (a.find("--neighbour")) 
+    {
+      vector<string> s = a.value("--neighbour",2);
+      par::min_neighbour = getInt(s[0].c_str(),"--neighbour");
+      par::max_neighbour = getInt(s[1].c_str(),"--neighbour");
+      par::outlier_detection = true;
+    }
+
+  if (a.find("--matrix")) par::matrix = true;
+  if (a.find("--distance-matrix")) { par::distance_matrix = par::matrix = true; }
+
+  if (a.find("--mds-plot")) 
+    {
+      par::cluster_plot = true;
+      par::cluster_mds_dim = a.value_int("--mds-plot");
+    }
+  
+  if (a.find("--mds-cluster"))
+    par::mds_by_individual = false;  
+      
+  if (a.find("--pmerge"))
+    error("--pmerge is depreciated: use --ppc instead\n");
+  
+  if (a.find("--ppc")) 
+    {
+      if (!par::cluster) error("--ppc options requires --cluster");
+      par::merge_p = a.value_double("--ppc");
+    }
+
+  if (a.find("--pibs-gap"))
+    error("--pibs-gap is depreciated: please use --ppc-gap\n");
+  
+  if (a.find("--ppc-gap"))
+    {
+      par::ibstest_gap = 1000 * a.value_int("--ppc-gap");
+    }
+  
+  if (a.find("--ibm"))
+    {
+      if (! a.find("--cluster"))
+	error("Can only use --ibm with --cluster\n");
+      par::cluster_ibm_constraint = true;
+      par::cluster_ibm_constraint_value = a.value_double("--ibm");      
+    }
+
+  if (a.find("--mc")) 
+    {
+      if (!par::cluster) error("--mc options requires --cluster");
+      par::max_cluster_size = a.value_int("--mc");
+    }
+
+  if (a.find("--cc")) 
+    {
+      if (!par::cluster) error("--cc options requires --cluster");
+      par::cluster_on_phenotype = true;
+    }
+  
+  if (a.find("--mcc")) 
+    {
+      if (!par::cluster) error("--mcc options requires --cluster");
+      par::cluster_on_mcc = true;
+      vector<string> s = a.value("--mcc",2);
+      par::max_cluster_case = getInt(s[0].c_str(),"--mcc");
+      par::max_cluster_control = getInt(s[1].c_str(),"--mcc");
+      if (a.find("--mc") || a.find("-cc"))
+	error("Cannot specify --mc N and/or --cc as well as --mcc N1 N2\n");
+    }
+
+
+
+  /////////////////////////////////
+  // External criteria to match on
+
+  // Categorical binary traits,
+  // by default
+  //  e.g. { A, A } is a match and so are pairable
+  //       { A, B } is not 
+  // 
+  //  if match-type file is also specifed, then matches 
+  //  can potentially be otherwise, e.g. 
+  //       { A, B } are pairable
+  //       { A, A } are not
+
+  if (a.find("--match")) 
+  {
+     par::bmatch = true;     
+     par::bmatch_filename = a.value("--match");
+  }
+
+  if (a.find("--match-type"))
+    {
+      if (!a.find("--match"))
+	error("Must specify a --match {file} with the --match-type {file} option");
+      par::bmatch_usertype = true;
+      par::bmatch_direction_filename = a.value("--match-type");
+    }
+
+  // Quantitative trait match
+  // Based on difference exceeding a certain threshold
+  // e.g. (X-Y)>T    => no match
+  //      (X-Y)<=T   => match
+
+  // T is specified by including an extra individual in the qmatch file
+  // with the Family ID and Individual ID "_T_" 
+
+  if (a.find("--qmatch"))
+  {
+     if (!a.find("--qt"))
+      error("You need to specify a --qt file when using --qmatch");
+     par::qmatch_threshold_filename = a.value("--qt");    
+     par::qmatch = true;     
+     par::qmatch_filename = a.value("--qmatch");
+  }
+
+
+
+  //////////////////////////
+  // Permutation clustering
+
+  if (a.find("--family")) 
+    {
+      par::sol_family = true;
+      par::permute_within_sol = true;
+      par::include_cluster = true;
+    }
+  
+  if (a.find("--within"))
+    {
+      par::permute_within_sol = par::include_cluster = true;            	
+      par::include_cluster_from_file = true;
+      par::include_cluster_filename = a.value("--within");
+    }
+
+  if (a.find("--mwithin"))
+    {
+      if (!a.find("--within"))
+	error("You can only specify --mwithin with --within");
+      par::mult_clst = a.value_int("--mwithin");
+    }
+
+  
+  //////////////////////////////////
+  // Specific scan region selected
+  
+  if (!a.find("--from"))
+    {
+      
+      // Specify a specific chromosome
+      string c="0";  // Default all chromosomes
+      
+      if (a.find("--chr")) 
+	c = a.value("--chr");
+      
+      if (c=="X" || c=="x") par::run_chr = 23;
+      else if (c=="Y" || c=="y") par::run_chr = 24;
+      else par::run_chr = getInt(c,"--chr");
+    }
+      
+  if (a.find("--from")) 
+    {
+      
+      if (!a.find("--to"))
+	error("Must also specify --to {marker} when using --from {marker}");
+	
+      par::m1 = a.value("--from");
+      par::m2 = a.value("--to");
+      par::run_chr = -1;
+    }
+  
+  if (a.find("--snp"))
+    {
+      par::m1 = a.value("--snp");
+      par::m2 = a.value("--snp");
+      par::run_chr = -1;      
+    }
+
+  if (a.find("--snps"))
+    {
+      par::extract_set = true; 
+      par::snp_include_from_cl = true;
+      par::snp_include_range = a.value("--snps");
+
+      if ( a.find("--snp") || a.find("--window") || a.find("--extract") || a.find("--exclude") )
+	error("Cannot specify multiple SNP-selection options with --snps");
+      
+    }
+
+  if ( a.find("--d") )
+    {
+      par::range_delimiter = a.value("--d");
+      if ( par::range_delimiter.length() > 1 )
+	error("Range delimiter can only be 1 character");
+      if ( par::range_delimiter == "," )
+	error("Cannot set range delimiter to comma");
+    }
+
+  if (a.find("--window"))
+    {
+      if (!a.find("--snp")) error("Must specify --snp with --window");
+      par::window = a.value_double("--window");
+    }
+
+  if (a.find("--from-bp"))
+    {
+      if (!a.find("--to-bp")) error("Must specify --to-bp with --from-bp");
+      par::from_window = a.value_int("--from-bp");
+      par::position_window = true;
+    }
+
+  if (a.find("--from-kb"))
+    {
+      if (!a.find("--to-kb")) error("Must specify --to-kb with --from-kb");
+      par::from_window = int(a.value_double("--from-kb") * 1000);
+      par::position_window = true;
+    }
+  
+  if (a.find("--from-mb"))
+    {
+      if (!a.find("--to-mb")) error("Must specify --to-mb with --from-mb");
+      double v = a.value_double("--from-mb");
+      if (v>1000) error("Too large a value for --from-mb");
+      par::from_window = int(v * 1000 * 1000);
+      par::position_window = true;
+    }
+  
+  
+  if (a.find("--to-bp"))
+    {
+      if (!a.find("--from-bp")) error("Must specify --from-bp with --to-bp");
+      par::to_window = a.value_int("--to-bp");
+      par::position_window = true;
+    }
+  
+  if (a.find("--to-kb"))
+    {
+      if (!a.find("--from-kb")) error("Must specify --from-kb with --to-kb");
+      par::to_window = int(a.value_double("--to-kb") * 1000);
+      par::position_window = true;
+    }
+
+  if (a.find("--to-mb"))
+    {
+      if (!a.find("--from-mb")) error("Must specify --from-mb with --to-mb");
+      double v = a.value_double("--to-mb");
+      if (v>1000) error("Too large a value for --to-mb");
+      par::to_window = int(v * 1000 * 1000);
+      par::position_window = true;
+    }
+
+  if (par::position_window)
+    if (!a.find("--chr"))
+      error("You must specify which chromosome (--chr N) also");
+  
+
+
+  ////////////////////////////////////////////
+  // General warnings
+
+  if ( a.find("--assoc") && a.find("--covar") )
+    error("Cannot specify --covar with --assoc");
+
+  if ( a.find("--model") && a.find("--covar") )
+    error("Cannot specify --covar with --model");
+
+  if ( a.find("--assoc") && a.find("--linear") )
+    error("Cannot specify --assoc with --linear");
+  
+  if ( a.find("--assoc") && a.find("--logistic") )
+    error("Cannot specify --assoc with --logistic");
+
+  if ( a.find("--model") && a.find("--linear") )
+    error("Cannot specify --model with --linear");
+  
+  if ( a.find("--model") && a.find("--logistic") )
+    error("Cannot specify --model with --logistic");
+
+  if ( a.find("--model") && a.find("--assoc") )
+    error("Cannot specify --model with --assoc");
+
+
+  /////////////////////////////////////////////
+  //  Help -- display all options
+
+  
+  if (a.find("--help") || a.find("-h"))
+    {
+
+      cout << "\n"
+	   << "Please visit the PLINK website for a complete list of options\n"
+	   << "\n"
+	   << "A few common options are listed here:\n"
+	   << "\n";
+
+      cout << "plink --file {fileroot}         Specify .ped and .map files \n"
+	   << "      --bfile {fileroot}        Specify .bed, .fam and .map \n"
+	   << "\n"
+	   << "      --out {fileroot}          Specify output root filename\n"
+	   << "\n"
+	   << "      --missing-genotype {0}    Missing genotype code       \n"
+	   << "      --missing-phenotype {-9}  Missing phenotype code      \n"
+	   << "\n"
+	   << "      --pheno {phenofile}       Specify .phe file           \n"
+	   << "      --within {file}           Specify cluster file        \n"
+	   << "      --cov {covarfile}         Specify .cov file           \n"
+	   << "\n"
+	   << "      --extract {snplist}       Extract list of SNPs        \n"
+	   << "      --exclude {snplist}       Exclude list of SNPs        \n"
+	   << "      --remove {indlist}        Remove these individuals    \n"
+	   << "      --keep {indlist}          Keep these individuals      \n"
+	   << "\n"
+	   << "      --make-bed                Make .bed, .fam and .bim    \n"
+	   << "      --recode                  Output new PED and MAP files\n"
+	   << "      --recode12                As above, with 1/2 alleles  \n"
+	   << "      --recodeAD                As above, but: 1/0/-1, 0/1/0\n"
+	   << "      --recodeA                 As above, but: 1/0/-1 only  \n"
+	   << "\n"
+	   << "      --snp {marker}            Specify this single SNP     \n"
+	   << "      --snps {marker list}      Specify list,range of SNPs  \n"
+	   << "      --window {kb}             Select +/- kb around --snp  \n"
+	   << "      --chr {N}                 Analyse chromosome          \n"
+	   << "      --from-kb {KB}            Start scan here (kilobase)  \n"
+	   << "      --to-kb {KB}              End scan here               \n"
+	   << "\n"
+           << "      --all                     Set filters to include all  \n"
+	   << "      --maf {0.01}              Minor allele frequency      \n"
+	   << "      --geno {0.1}              Maximum per-SNP missing     \n"
+	   << "      --mind {0.1}              Maximum per-person missing  \n"
+	   << "\n"
+	   << "      --freq                    Output allele frequencies   \n"
+	   << "      --hardy                   Hardy-Weinberg tests        \n"
+	   << "      --missing                 Genotyping rate information \n"
+	   << "      --het                     Individual inbreeding       \n"
+	   << "      --genome                  Genome-wide IBS/IBD         \n"
+	   << "      --cluster                 Perform IBS clustering      \n"
+	   << "\n"
+	   << "      --assoc                   Case/control, QT association\n"
+	   << "      --model                   Full-model C/C association  \n"
+	   << "      --tdt                     Family-based TDT association\n"
+	   << "      --linear                  Linear regression model     \n"
+	   << "      --logistic                Logistic regression model   \n"
+	   << "\n"
+ 	   << "      --perm                    Apaptive permutations       \n"
+ 	   << "      --mperm {1000}            max(T) permutations         \n"
+	   << "\n"
+	   << "      --hap {tagfilename}       Multimarker predictor list  \n"
+	   << "      --hap-window {N}          Phase sliding window        \n"
+	   << "      --hap-snps {snp list}     Phase this set of SNPs      \n" 
+	   << "      --hap-assoc               Haplotype-based association \n"
+	   << "      --hap-tdt                 Haplotype-based TDT         \n"
+	   << "      --chap                    Conditional haplotype tests \n"
+	   << "      --hap-phase               Report haplotype phases     \n"
+	   << "      --hap-freq                Report haplotype frequencies\n"
+	   << "\n";      	
+      
+      cout << "\nPlease visit the PLINK website for a complete list of options\n\n";
+
+      shutdown();
+    }
+  
+  
+  // By default, most tests are SNP major
+  
+  par::SNP_major = true;
+  
+  // Exceptions are:
+  //  TDT  ( family structure confuses things)
+  //  Whole genome / IBS clustering 
+  //  PLINK
+  
+  if (par::TDT_test || 
+      par::MENDEL_test || 
+      par::MENDEL_report || 
+      par::genome_output || 
+      par::cluster || 
+      par::plink )
+    par::SNP_major = false;
+  
+  if (a.find("--ind"))
+    par::SNP_major = false;
+  
+
+  // If recoding data, the default will be not to set heterozygous
+  // haploid genotypes to missing. Likewise for Mendel errors. Merge
+  // operations will also specify a recode/make-bed, so they are also
+  // captured here. The one special case where we want to allow to
+  // preserve males hets on the X is the --check-sex
+
+  
+  if ( par::check_sex )
+    par::preserve_all_genotypes = true;
+	  
+  if ( par::write_bitfile || 
+       par::recode || 
+       par::recode_HV ||
+       par::recode_whap ||
+       par::recode_12 ||
+       par::recode_AD )
+    {
+      
+      // Unless flag given, these options will not replace haploid
+      // heterozygotes with a missing genotype
+      
+      if ( a.find("--set-hh-missing") )
+	par::preserve_all_genotypes = false;
+      else
+	par::preserve_all_genotypes = true;
+
+      if ( a.find("--set-me-missing") )
+	par::preserve_mendel_errors = false;
+      else
+	par::preserve_mendel_errors = true;
+      
+    }
+
+
+}
+

Added: trunk/packages/plink/trunk/.pc/gcc43.patch/perm.cpp
===================================================================
--- trunk/packages/plink/trunk/.pc/gcc43.patch/perm.cpp	                        (rev 0)
+++ trunk/packages/plink/trunk/.pc/gcc43.patch/perm.cpp	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,507 @@
+
+
+//////////////////////////////////////////////////////////////////
+//                                                              //
+//           PLINK (c) 2005-2008 Shaun Purcell                  //
+//                                                              //
+// This file is distributed under the GNU General Public        //
+// License, Version 2.  Please see the file COPYING for more    //
+// details                                                      //
+//                                                              //
+//////////////////////////////////////////////////////////////////
+
+
+#include "perm.h"
+#include "helper.h"
+#include <iostream>
+#include <cmath>
+
+Perm::Perm(Plink & pref) : P(pref)
+{
+  
+  if (par::adaptive_perm) 
+    {
+      adaptive = true;
+      replicates = par::adaptive_max;
+    }
+  else
+    {
+      adaptive = false;
+      replicates = par::replicates;
+    }
+  
+  count = par::perm_count;
+  
+  min = par::adaptive_min;
+  
+  interval  = par::adaptive_interval;  
+  performed = 0;
+
+  dump_all = par::mperm_save_all;
+  dump_best = par::mperm_save_best;
+
+  if (dump_all)
+    {
+      PDUMP.open((par::output_file_name+".mperm.dump.all").c_str(),ios::out);
+    }
+  else if (dump_best)
+    {
+      PDUMP.open((par::output_file_name+".mperm.dump.best").c_str(),ios::out);
+    }
+}
+
+
+void Perm::setTests(int x) 
+{ 
+
+  performed = 0;
+
+  t = x;
+  R.resize(t);
+  
+  if (adaptive)
+    {
+      N.resize(t);
+      test.resize(t);
+      for (int i=0; i<t; i++) 
+	{
+	  test[i] = true;
+	  R[i] = N[i] = 0;
+	}
+
+      // Given t tests, set the threshold to be 
+      // p +/-  Phi^{-1} (1 - \gamma/2t ) sqrt( p(1-p)/N )
+      zt = ltqnorm( 1 - par::adaptive_ci / ( 2 * t ) ) ; 
+     
+    }
+  else
+    {
+      maxR.resize(t);
+      for (int i=0; i<t; i++) 
+	R[i] = maxR[i] = 0;      
+    }
+
+  // For gene-dropping, set up some family-information
+  if (par::perm_genedrop)
+    preGeneDrop();
+
+}
+
+void Perm::originalOrder()
+{
+  for (int i=0; i<P.n; i++)
+    P.sample[i]->pperson = P.sample[i];
+}
+
+
+bool Perm::finished()
+{
+  if (performed>=replicates) return true;  
+  else return false;
+}
+
+
+void Perm::permuteInCluster()
+{
+
+  // Store remapped IDs
+  vector<vector< long int> > i(ns);
+  
+  // Permute phenotypes, within cluster
+  for (int k=0; k<ns; k++)
+    {
+      vector<long int> p(s[k].size());
+      permute(p);
+      i[k]=p;
+    }
+
+  //////////////////////////
+  // Post-permutation:
+  // Iterate over clusters { s[][] }
+  // i[][] holds the permuted codes
+  // s[][] points to individuals (non-missing)
+  
+  // Genotype =           sample[s[j][k]];	    
+  // Matching phenotype = sample[s[j][(int)i[j][k]]];	    
+
+  // Create pheno[] with label-swapped codes
+  for (int j=0; j<s.size(); j++)
+    for (int k=0; k<s[j].size(); k++)
+      P.sample[s[j][k]]->pperson = P.sample[s[j][(int)i[j][k]]];
+  
+}
+
+void Perm::setPermClusters(Plink & P)
+{
+  
+  // Permute within clusters only
+  // (stored in sample[i]->sol) 
+  
+  // Get list of non-missing individuals, and number of solutions
+  // These are always numbered 0,1,2,3,..
+  
+  // -1 indicates do not permute this individual
+  // 0..ns indicate cluster numbers
+  
+  // Count the number of clusters: 'ns'
+  
+  ns=-1;
+  for (int i=0; i<P.n; i++)
+    if ((!P.sample[i]->missing) && P.sample[i]->sol > ns)
+      ns=P.sample[i]->sol;
+  ns++;
+  
+  // store set membership is 's' 
+  
+  s.resize(ns);
+  for (int i=0; i<P.n; i++)
+    if (!P.sample[i]->missing && P.sample[i]->sol>=0)
+      s[P.sample[i]->sol].push_back(i);
+  
+  pheno.resize(P.n);
+
+  if (par::permute && ! par::QTDT_test )
+    P.printLOG("Set to permute within "+int2str(ns)+" cluster(s)\n");
+
+}
+
+void Perm::setOriginalRanking(vector_t & original)
+{
+  vector<Pair2> o;
+  for (int i=0; i<original.size(); i++)
+    {
+      Pair2 p;
+      p.p = original[i];
+      p.l = i;
+      o.push_back(p);
+    }
+
+  sort(o.begin(),o.end());
+
+  order.clear();
+  reorder.resize(original.size());
+  for(int i=0; i<original.size(); i++)
+    {
+      order.push_back(o[i].l);
+      reorder[o[i].l] = i;
+    }
+}
+
+
+
+bool Perm::update(vector<double> & result, vector<double> & original)
+{
+  
+  // Increment number of permutations performed
+  performed++;
+    
+  // Finished all perms?
+  bool done = false;
+  
+  //////////////////////////////
+  // Update number of successes
+  
+  if (!adaptive)
+    {
+      for (int l=0; l<t; l++)
+	if (result[l] >= original[l] || !realnum(original[l]) ) R[l]++;
+    }
+  else
+    {
+      for (int l=0; l<t; l++)
+	if (test[l]) 
+	  {
+	    if (result[l] >= original[l]  || !realnum(original[l]) ) R[l]++;      
+	    N[l]++;
+	  }
+    }
+	
+
+  // Stopping rules for adaptive permutation?
+  int todo = 0;
+  if (adaptive && 
+      performed > min && 
+      performed % interval == 0)
+    {
+      
+      // Update interval
+      interval = (int)(par::adaptive_interval + performed * par::adaptive_interval2);
+
+      // Consider each test
+      for (int l=0; l<t; l++)
+	{
+	  if (test[l])
+	    {
+	      
+	      // Check for at least one success
+	      if (R[l]>0)
+		{
+		  double pv = (double)(R[l]+1)/(double)(performed+1);
+		  
+		  double sd = sqrt( pv * (1-pv) / performed );
+		  double lower = pv - zt * sd;
+		  double upper = pv + zt * sd;
+		  //double cv = sd/(performed*pv);
+		  if (lower<0) lower = 0;
+		  if (lower>1) upper = 0;
+
+		  // Is lower bound greater than threshold, or 
+		  // upper bound smaller than threshold?
+		  if (lower > par::adaptive_alpha || upper < par::adaptive_alpha ) 
+		    {
+		      N[l] = performed;
+		      test[l] = false;
+		    }
+		  
+		  else
+		    todo++;
+		}
+	      else todo++;
+	    }
+	}
+      
+      if (!par::silent)
+	cout << "Adaptive permutation: "
+	     << performed
+	     << " of (max) " 
+	     << replicates 
+	     << " : " 
+	     << todo 
+	     << " SNPs left"
+	     << "          \r";
+      
+      if (todo==0) done = true;
+    }
+
+  
+  ///////////////////////////////////////////////////////////
+  // For non-adaptive permutation, keep track of the maximum
+  
+  if (!adaptive)
+    {
+      
+      if (dump_all)
+	{
+	  if (performed==1)
+	    {
+	      PDUMP << 0 << " ";
+	      for (int l=0; l<t; l++)
+		PDUMP << original[l] << " ";
+	      PDUMP << "\n";
+	    }
+	  PDUMP << performed << " ";
+	}
+      
+      
+      if (dump_best)
+	{
+	  if (performed==1)
+	    {
+	      PDUMP << 0 << " ";
+	      
+	      double mx=0;
+	      for (int l=0; l<t; l++)
+		if (original[l]>mx) 
+		  if ( realnum(mx)) 
+		    mx=original[l];
+	      PDUMP << mx << "\n";
+	    }
+	  PDUMP << performed << " ";
+	}
+      
+      
+      // Find maximum, or sort all results
+      
+      double mx=0;
+
+      if ( par::mperm_rank )
+	{
+	  // Ranked permutation
+	  // populate mx vector
+
+	  // Set any NA to 0
+	  for (int l=0; l<t; l++)
+	    if ( ! realnum(result[l]) )
+	      result[l] = 0;
+	  
+	  // Sort (ascending)
+	  sort(result.begin(),result.end());
+
+	  // Save max in any case
+	  mx = result[result.size()-1];
+	}
+      else
+	{
+	  // Standard max(T)
+	  // populate single mx variable
+	  for (int l=0; l<t; l++)
+	    if (result[l]>mx) 
+	      if ( realnum(mx) ) 
+		mx=result[l];
+	}
+
+
+      if (dump_best)
+	PDUMP << mx << "\n";
+      else if (dump_all)
+	{
+	  for (int l=0; l<t; l++)
+	    PDUMP << result[l] << " ";
+	  PDUMP << "\n";
+	}
+      
+
+      // Max(T) permutation -- compare against best
+
+      if ( ! par::mperm_rank )
+	{
+	  for (int l=0; l<t; l++)
+	    if (mx >= original[l] || !realnum(original[l]) ) maxR[l]++;
+	}
+	  
+      // Rank(T) permutation -- compare against similar rank
+      
+      else
+	{
+	  for (int l=0; l<t; l++)
+	    {
+	      //cout << "P " << order[l] << " " << original[order[l]] << " , pr = " << result[l] << " ";
+	
+	      if (result[l] >= original[order[l]] || !realnum(original[order[l]]) )
+		maxR[order[l]]++;
+		
+	    }
+	}
+
+
+
+      if (!par::silent)
+	{
+	  cout << "maxT permutation: "
+	       << performed
+	       << " of " 
+	       << par::replicates 
+	       << "            \r";
+	  cout.flush();
+	}
+    }  
+  
+  // Have we hit the maximum number of replicates?
+  if (performed>=replicates) done = true;
+
+  return done;
+}
+
+void Perm::nextSNP()
+{
+  // Reset Perm class for next SNP when in adaptive, SNP-by-SNP mode
+  performed = 0;
+  originalOrder();
+}
+
+bool Perm::updateSNP(double result, double original, int l)
+{
+  
+  /////////////////////////////////////////
+  // Single SNP adaptive permutation update
+  /////////////////////////////////////////
+
+  // Increment number of permutations performed for this SNP
+  performed++;
+    
+  // Finished all perms for this SNP?
+  bool done = false;
+  
+  //////////////////////////////
+  // Update number of successes
+
+  if (test[l]) 
+    {
+      if (result >= original  || !realnum(original) ) R[l]++;      
+      N[l]++;
+    }
+    
+
+  // Stopping rules for adaptive permutation?
+
+  if (adaptive && 
+      performed > min && 
+      performed % interval == 0)
+    {
+      
+      // Update interval
+      interval = (int)(par::adaptive_interval + performed * par::adaptive_interval2);
+
+      // Consider this specific SNP
+      if (test[l])
+	{
+	  
+	  // Check for at least one success
+	  if (R[l]>0)
+	    {
+	   
+	      double pv = (double)(R[l]+1)/(double)(performed+1);
+	      
+	      double sd = sqrt( pv * (1-pv) / performed );
+	      double lower = pv - zt * sd;
+	      double upper = pv + zt * sd;
+	      //double cv = sd/(performed*pv);
+	      if (lower<0) lower = 0;
+	      if (lower>1) upper = 0;
+	      
+	      // Is lower bound greater than threshold, or 
+	      // upper bound smaller than threshold?
+	      if (lower > par::adaptive_alpha || upper < par::adaptive_alpha ) 
+		{
+		  N[l] = performed;
+		  test[l] = false;
+		  done = true;
+		}
+	    }
+	}
+            
+    }
+  
+  // Have we hit the maximum number of replicates?
+  if (performed>=replicates) done = true;
+  
+  return done;
+}
+
+
+int Perm::rank(int l)
+{
+  if ( ! par::mperm_rank )
+    return 0;
+  else
+    return t - reorder[l];
+  
+}
+
+double Perm::pvalue(int l)
+{
+  if (count)
+    return (double)R[l];
+  if (adaptive)
+    return (double)(R[l]+1) / (double)(N[l]+1);
+  else
+    return (double)(R[l]+1) / (double)(replicates+1);
+}
+
+
+double Perm::max_pvalue(int l)
+{
+  if (adaptive)
+    return -1;
+  else
+    return (double)(maxR[l]+1) / (double)(replicates+1);
+}
+
+int Perm::reps_done(int l)
+{
+  if (adaptive)
+    return N[l];
+  else
+    return replicates;
+}
+

Added: trunk/packages/plink/trunk/.pc/gcc43.patch/prephap.cpp
===================================================================
--- trunk/packages/plink/trunk/.pc/gcc43.patch/prephap.cpp	                        (rev 0)
+++ trunk/packages/plink/trunk/.pc/gcc43.patch/prephap.cpp	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,656 @@
+
+
+//////////////////////////////////////////////////////////////////
+//                                                              //
+//           PLINK (c) 2005-2007 Shaun Purcell                  //
+//                                                              //
+// This file is distributed under the GNU General Public        //
+// License, Version 2.  Please see the file COPYING for more    //
+// details                                                      //
+//                                                              //
+//////////////////////////////////////////////////////////////////
+
+
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <sstream>
+#include <cmath>
+#include <vector>
+#include <map>
+
+#include "plink.h"
+#include "options.h"
+#include "phase.h"
+#include "helper.h"
+#include "nlist.h"
+
+extern ofstream LOG;
+
+using namespace std;
+
+// Format for haplotype file: format 1:
+// SNP_ID  CHR  CM  BP  A1 A2   HAP   SNP1  SNP2 ... 
+
+// i.e. length of Pred_allele indicate how many SNPs to expect:
+// rs10001 5 0 10203  A G   TTC  rs001 rs002 rs003
+
+// Alternatively: using wild cards: format 2:
+// will name haplotype "H1_TTC_", "H1_CTT_", "H2_AA_", etc
+// * rs001 rs002 rs003
+// * rs002 rs004
+
+// Alternatively: using wild cards: format 3:
+// will name haplotype "MYHAP1_1_TTC_", "MYHAP1_1_CTT_", "GENEB_2_AA_", etc
+// ** MYHAP1 rs001 rs002 rs003
+// ** GENEB rs002 rs004
+
+// Alternatively: using --whap weighted multimarker tests
+// rs10001 5 0 10203  A G   rs001 rs002 rs003 / TTC / CCT 0.9 / TCT 0.1 
+// i.e. "/" separator used, if number omitted, then assume PP=1
+
+void HaploPhase::readTagFile()
+{
+
+  P.printLOG("\n");
+
+  ///////////////////////////////////////////////
+  // Haplotype inference is a SNP-major function
+  
+  if (!par::SNP_major) P.Ind2SNP();
+
+
+  ////////////////////////
+  // Lookup table for SNPs
+
+  map<string,int> mlocus;
+  map<string,int>::iterator ilocus;
+  
+  for (int l=0;l<P.nl_all;l++)
+    mlocus.insert(make_pair(P.locus[l]->name,l));
+
+
+  ///////////////////
+  // Affection coding
+
+  if (par::bt) affCoding(P);
+
+  
+  ////////////////////////////////
+  // Read list of tags/haplotypes
+
+  checkFileExists(par::tagfile);
+  ifstream TAG(par::tagfile.c_str(), ios::in);
+  TAG.clear();
+  
+  string f2 = par::output_file_name + ".mishap";
+  ofstream MISHAP(f2.c_str(), ios::out);
+  bool all_okay = true;
+
+  // Count of new haplotypes we want to infer
+  int hc=1; 
+  
+  while(!TAG.eof())
+    {
+      char c[500000];
+      TAG.getline(c,500000,'\n');
+      
+      string l = c;
+
+      // Catch blank lines or DOS carriage-returns
+      if (l=="" || l=="\r") continue;
+
+      // Tokenize line
+      string buf; 
+      stringstream ss(l); 
+      vector<string> tokens; 
+      while (ss >> buf)
+	tokens.push_back(buf);
+      
+      // whitepsace line?
+      if (tokens.size() == 0)
+	continue;
+      
+      // tokens[0]  predicted SNP rs#
+      // tokens[1]  predicted SNP chromosome
+      // tokens[2]  predicted SNP Morgan position
+      // tokens[3]  predicted SNP base pair position
+      // tokens[4]  predicted SNP allele 1
+      // tokens[5]  predicted SNP allele 2
+      // tokens[6]  tag allele (-> allele 1)
+      // tokens[7+] predictor rs#(s)
+
+
+      // If we see one or more wildcard specifications, then
+      // automatically set phase_all_haps to be true;
+
+      if ( tokens[0] == "*" )
+	{ 
+	  // Wildcard format
+
+	  if ( tokens.size() == 1 )
+	    error("Problem with " + 
+		  par::tagfile + " line\n" + l 
+		  + "\n: must have atleast one SNP list\n");
+
+	  par::phase_hap_all = true; 
+	}
+      else if ( tokens[0] == "**")
+	{ 
+	  // Wildcard2 format
+	  
+	  if (tokens.size() == 2 )
+	    error("Problem with " 
+		  + par::tagfile + " line\n" + l 
+		  + "\n: must have atleast one SNP list\n");
+
+	  par::phase_hap_all = true; 
+
+	}
+      else if ( ! par::weighted_mm )
+	{
+	  // Standard format
+
+	  if (tokens.size() < 8 ) 
+	    {
+	      string e = "Problem with " + 
+		par::tagfile + " line\n" 
+		+ l + 
+		"\n (expecting at least 8 items, or to start with */** wildcard)\n";
+	      error(e);	  
+	    }
+	} 
+      else
+	{
+	  // Weighted multi-marker format
+	  
+	  
+	  if (tokens.size() < 9 ) 
+	    {
+	      string e = "Problem with " + par::tagfile + " line\n" 
+		+ l 
+		+ "\n (expecting at least 9 items for --whap format file)\n";
+	      error(e);	  
+	    }
+
+
+	}
+ 
+      if (tokens[0].substr(tokens[0].size()-1) == "_" ) 
+	error("Cannot use '_' in tag/haplotype name: reserved for wildcards\n");
+
+
+      int len; 		        // length of haplotype
+      vector<int> locusList;	// list of predictor #s
+      
+    
+      // Is this particular line a wildcard? okay?
+      bool wildcard = tokens[0] == "*" || tokens[0] == "**" ? true : false ;
+      string wildname = "H";
+      
+      // Take the name from the second position? (** wildcard?) 
+      if ( tokens[0] == "**" )
+	{
+	  wildname = tokens[1]+"_";
+	  tokens.erase(tokens.begin()+1);
+	}
+
+      bool okay = true;
+
+
+
+
+      /////////////////////////////////
+      // Fully-specified haplotype 
+      
+      if (!wildcard) 
+	{
+	  
+	  int offset = 7;
+	  if ( par::weighted_mm ) offset = 6;
+
+	  if ( par::weighted_mm )
+
+	    {
+	      // Find first "/" separator
+	      int sep = 6;
+	      while ( tokens[++sep] != "/" ) { }
+	      len = sep - 6;
+	    }
+	  else
+	    {
+	      len = tokens[6].length();
+	      
+	      if (len != tokens.size() - offset )
+		{
+		  string e = "Problem with " + 
+		    par::tagfile + " line\n" + l + "\n";
+		  error(e);
+		}      
+	    }
+
+	  
+	  //////////////////////
+	  // Lookup locus name
+	  
+	  for (int i=0; i<len; i++)
+	    {
+	      ilocus = mlocus.find(tokens[i+offset]);
+	      if (ilocus != mlocus.end())
+		{
+		  locusList.push_back(ilocus->second);	  	  
+		}
+	      else 
+		{
+		  MISHAP << "NOSNP\t" << tokens[0] 
+			 << "\t" << tokens[i+offset] << "\n";
+		  okay = false;
+		}
+	    }
+	  
+
+	  /////////////////////////////////
+	  // Check specified alleles exist	  
+
+	  if (okay)
+	    {
+
+	      // Just one haplotype to check for non-weighted test version
+	      
+	      if ( ! par::weighted_mm )
+		{
+		  for (int s=0;s<len;s++)
+		    if ( ! ( P.locus[locusList[s]]->allele1 
+			     == tokens[6].substr(s,1) 
+			     || P.locus[locusList[s]]->allele2 
+			     == tokens[6].substr(s,1) ) )
+		      {
+			MISHAP << "NOALLELE\t" << tokens[0] 
+			       << "\t" << P.locus[locusList[s]]->name
+			       << "\t" << tokens[6] << "\n";
+			okay = false;
+		      }
+		}
+
+	      // Otherwise, we must parse through and check each
+	      else
+		{
+		  
+		  int allele = 5 + len + 2;
+
+		  for ( int i = allele ; i < tokens.size() ; i++ ) 
+		    {
+		      // Is this a haplotype?
+		      if ( i == allele || tokens[i-1] == "/" )
+			{
+			  for (int s=0;s<len;s++)
+			    if ( ! ( P.locus[locusList[s]]->allele1 
+				     == tokens[i].substr(s,1) 
+				     || P.locus[locusList[s]]->allele2 
+				     == tokens[i].substr(s,1) ) )
+			      {
+				MISHAP << "NOALLELE\t" << tokens[0] 
+				       << "\t" << P.locus[locusList[s]]->name
+				       << "\t" << tokens[i] << "\n";
+				okay = false;
+			      }
+			}
+		    }
+		}
+
+	    }
+
+	  
+	}
+      else
+	{
+	  /////////////////////////////////
+	  // Wildcard selection
+
+          len = tokens.size()-1;
+
+          // Lookup locus name
+          for (int i=0; i<len; i++)
+	    {
+	      ilocus = mlocus.find(tokens[i+1]);
+	      if (ilocus != mlocus.end())
+		{
+		  locusList.push_back(ilocus->second);	  	  
+		}
+	      else 
+		{
+		  MISHAP << "NOSNP\t" << tokens[i+1] << "\n";
+		  okay = false;
+		}
+	    }
+	}
+      
+
+
+      //////////////////////////////////////
+      // Should we try to add this haploype
+           
+      if (!okay) 
+	{
+	  all_okay = false;
+	  continue;
+	}
+
+
+      ////////////////////////////////////////////////////////
+      // Check that all predictors are on the same chromosome
+      
+      if (!wildcard)  
+	{    
+	  for (int ck=0; ck<len; ck++)
+	    if (P.locus[locusList[ck]]->chr != atoi(tokens[1].c_str()))
+	      {
+		MISHAP << "DIFF_CHR\t" << P.locus[locusList[ck]]->name 
+		       << "\t" << tokens[0] << "\n";	  
+		okay = false;
+	      }
+	}
+      else
+	{	
+	  for (int ck=0; ck<len-1; ck++)
+	    if (P.locus[locusList[ck]]->chr != P.locus[locusList[ck+1]]->chr)
+	      {
+		MISHAP << "DIFF_CHR\t" << P.locus[locusList[ck]]->name 
+		       << "\t" << P.locus[locusList[ck+1]]->name << "\n";
+		okay = false;
+	      }
+	}
+      
+      if (!okay) 
+	{
+	  all_okay = false;
+	  continue;
+	}
+      
+      
+      ///////////////////////////////////////
+      // Standard approach -- only one entry
+	
+      if ( ( !wildcard) && (!par::weighted_mm) )
+	{
+	  
+	  // Add numbers for predictors to list
+	  new_pred_locus.push_back(locusList);
+	  
+	  // Add which allele to look for (corresponding to allele1)
+	  new_pred_allele.push_back(tokens[6]);
+	  
+	  // Make new entry in MAP file
+	  Locus * loc = new Locus;
+	  loc->name = tokens[0];
+	  loc->chr = getChromosomeCode( tokens[1] );
+	  loc->pos = atof(tokens[2].c_str());
+	  loc->bp = atoi(tokens[3].c_str());  
+	  loc->allele1 = tokens[4];
+	  loc->allele2 = tokens[5];
+	  
+	  // Add this new locus to the list
+	  new_map.push_back(loc);
+	}
+      else if ( ( !wildcard ) && par::weighted_mm )
+	{
+
+	  ///////////////////////////////////////
+	  // Weighted MM test -- only one entry
+
+  	  // Add numbers for predictors to list
+	  new_pred_locus.push_back(locusList);
+	  
+	  // Add which allele(s) to look for (corresponding to allele 1)
+	  // and then the corresponding weights
+	  
+	  map<string,double> whap;
+
+	  int index = 5 + len + 2;
+	  while ( index < tokens.size() ) 
+	    {
+	      // Read haplotype, then optionally a weight
+	      
+	      if ( tokens[index].size() != len )
+		error("Problem with " + par::tagfile + " line\n" + l + "\n");
+	      
+	      // Read weight, or advance to next haplotype?
+	      if ( index == tokens.size() - 1 )
+		{
+		  whap.insert(make_pair( tokens[index] , 1 ) );
+		  break;
+		}
+	      else if ( tokens[index+1] == "/" )
+		{
+		  whap.insert(make_pair( tokens[index] , 1 ) );
+		  index += 2;
+		}
+	      else
+		{
+		  double w = atof(tokens[index+1].c_str());
+		  if ( ( !realnum(w) ) ||
+		       w < 0 || w > 1 ) 
+		    error("Problem with specified weight in line:\n"+l+"\n");
+		  whap.insert(make_pair( tokens[index] , w ) );
+		  index += 3;
+		}
+	    }
+
+	  
+	  new_pred_weighted_allele.push_back(whap);
+	  
+	  // Make new entry in MAP file
+	  Locus * loc = new Locus;
+	  loc->name = tokens[0];
+	  loc->chr = getChromosomeCode( tokens[1] );
+	  loc->pos = atof(tokens[2].c_str());
+	  loc->bp = atoi(tokens[3].c_str());  
+	  loc->allele1 = tokens[4];
+	  loc->allele2 = tokens[5];
+	  
+	  // Add this new locus to the list
+	  new_map.push_back(loc);
+
+
+	  
+	}
+      else
+	{
+
+	  ////////////////////////////////////////////
+	  // Wildcard approach -- just a single entry
+
+	  // Add numbers for predictors to list
+	  new_pred_locus.push_back(locusList);
+	      
+	  // Put in a dummy allele code (we ignore this...)
+	  string hstr="";
+	  for (int s=0;s<S.size();s++)
+	    hstr += P.locus[locusList[s]]->allele1;
+		  
+	  new_pred_allele.push_back(hstr);
+		
+	  // Make new entry in MAP file
+	  
+	  Locus * loc = new Locus;
+	  loc->name = wildname +int2str(hc)+"_DUMMY_"+hstr+"_";
+	  loc->chr = P.locus[locusList[0]]->chr;
+	  loc->pos = 0;
+	  loc->bp = hc; 
+	  loc->allele1 = "1";
+	  loc->allele2 = "2";
+	  
+	  // Add this new locus to the list
+	  new_map.push_back(loc);
+	  
+	   	  
+	}
+
+      // Increment new haplotype count
+      hc++;
+      
+      // Read next in TAG file
+
+    }
+
+  TAG.close();
+  MISHAP.close();
+
+  if (!all_okay)
+    P.printLOG("Warning: misspecified haplotypes found: listed in [ " + f2 + " ]\n");
+
+  
+  // End of reading haplotype list -- did we encounter any problems?
+
+  P.printLOG("Read " + int2str(new_map.size()) + 
+	   " haplotypes from [ " + par::tagfile + " ]\n");  
+
+}
+
+
+
+void HaploPhase::makeSlidingWindow(int winsize, int winstep)
+{
+  
+  P.printLOG("\n");
+  
+  ///////////////////////////////////////////////
+  // Haplotype inference is a SNP-major function
+  
+  if (!par::SNP_major) 
+    P.Ind2SNP();
+
+
+  //////////////////////////////////
+  // Set up haplotype entries
+
+  int w=1;
+
+  int start = 0;
+
+  while ( 1 )
+    {
+
+      // Beyond last SNP?
+      
+      if ( start >= P.nl_all ) 
+	break;
+      
+      // Make a window, as large as possible
+      vector<int> snps;
+
+      // Make sure it is restricted to one chromosome
+      int chr = P.locus[start]->chr;
+      
+      bool fail = false;
+      bool newChromosome = false;
+      int actualStop = start;
+
+      // Add SNPs to window
+
+      for (int s = start; s < start + winsize; s++)
+	{
+	  
+	  // No more SNPs left 
+	  if ( s == P.nl_all  ) 
+	    {
+	      fail = true;
+	      break;
+	    }
+	  
+	  // Next chromosome?
+	  if ( P.locus[s]->chr != chr )
+	    {	      
+	      newChromosome = true;
+	      actualStop = s;
+	      break;
+	    }
+	  
+	  snps.push_back(s);	  
+	  actualStop = s;
+	}
+      
+      // Have we come up to the end of this chromosome in an exact number?
+      if ( actualStop == P.nl_all-1 )
+	{
+	  fail = true;
+	}
+      else if ( ( ! newChromosome ) && P.locus[actualStop+1]->chr != chr )
+	{
+	  newChromosome = true;
+	  actualStop++;
+	}
+      
+
+      // Finished constructing this particular window: 
+      // do we have anything to add?
+
+      if ( snps.size() == 0 )
+	{
+	  if ( newChromosome )
+	    start = actualStop;
+	  else
+	    start += winstep;
+	  continue;
+	}
+
+      Locus * tmploc = new Locus;
+      tmploc->name = "WIN"+int2str(w++);
+      tmploc->chr = P.locus[start]->chr;
+      tmploc->pos = P.locus[start]->pos;
+      tmploc->bp = P.locus[start]->bp;
+      tmploc->allele1 = "1";
+      tmploc->allele2 = "2";
+      new_pred_locus.push_back(snps);
+
+      new_map.push_back(tmploc);
+      new_pred_allele.push_back("");
+
+
+      // Advance window
+      
+      if ( fail )
+	break;
+
+      if ( newChromosome )
+	start = actualStop;
+      else
+	start += winstep;
+      
+    }
+      
+   P.printLOG("Created " + int2str(w-1) + " sliding windows\n");
+
+}
+
+
+void HaploPhase::setSpecificSNPs(string snps)
+{
+
+  map<string,int> mapping;
+  for (int l=0; l<P.nl_all;l++)
+    mapping.insert(make_pair(P.locus[l]->name,l));
+  
+  NList nl(P.nl_all,true);   
+  vector<int> snplist = nl.deparseStringList(snps,&mapping);
+  
+  if (snplist.size() == 0 )
+    return;
+  
+  int start = snplist[0];
+
+  new_pred_locus.push_back(snplist);
+  
+  Locus * tmploc = new Locus;
+  tmploc->name = "WIN1";
+  tmploc->chr = P.locus[start]->chr;
+  tmploc->pos = P.locus[start]->pos;
+  tmploc->bp = P.locus[start]->bp;
+  tmploc->allele1 = "1";
+  tmploc->allele2 = "2";	      
+  new_map.push_back(tmploc);
+  
+  new_pred_allele.push_back("");		      
+  
+  return;
+}

Added: trunk/packages/plink/trunk/.pc/gcc43.patch/proxy.cpp
===================================================================
--- trunk/packages/plink/trunk/.pc/gcc43.patch/proxy.cpp	                        (rev 0)
+++ trunk/packages/plink/trunk/.pc/gcc43.patch/proxy.cpp	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,1593 @@
+
+
+//////////////////////////////////////////////////////////////////
+//                                                              //
+//           PLINK (c) 2005-2008 Shaun Purcell                  //
+//                                                              //
+// This file is distributed under the GNU General Public        //
+// License, Version 2.  Please see the file COPYING for more    //
+// details                                                      //
+//                                                              //
+//////////////////////////////////////////////////////////////////
+
+
+#include <iostream>
+#include <iomanip>
+#include <string>
+#include <set>
+#include <cmath>
+#include "options.h"
+#include "helper.h"
+#include "plink.h"
+#include "phase.h"
+#include "model.h"
+#include "linear.h"
+
+//////////////////////////////////////////
+// Helper classes to store and sort proxies
+
+class ProxyResult {
+public:
+
+  string name;
+  double f;
+  double r2;
+  double odds;
+  double chisq;
+  double pvalue;
+
+  ProxyResult(string n, double frq, double r, double o, double c, double p)
+    : name(n), f(frq), r2(r), odds(o), chisq(c), pvalue(p) { } 
+
+  bool operator< (const ProxyResult & b) const
+    {
+      return ( pvalue == b.pvalue ? 
+	       name < b.name : 
+	       pvalue < b.pvalue );
+    }
+};
+
+
+class LDPair {
+public:
+  int s1;
+  int s2;
+  double ld;
+  bool operator< (const LDPair & b) const
+  {
+    return  ld > b.ld;
+  }
+
+
+}; 
+
+
+///////////////////////////////////////////////
+// Helper function to find n of m combinations
+
+void combinations_recursive(const vector<int> &elems,
+			    unsigned long req_len,
+			    vector<unsigned long> &pos,
+			    unsigned long depth,
+			    unsigned long margin,
+			    vector<vector<int> > & collection)
+{
+  
+  if (depth >= req_len) {
+    vector<int> t;
+    for (unsigned long ii = 0; ii < pos.size(); ++ii)
+      t.push_back( elems[pos[ii]] );
+    collection.push_back(t);
+    return;
+  }
+
+  if ((elems.size() - margin) < (req_len - depth))
+    return;
+
+  for (unsigned long ii = margin; ii < elems.size(); ++ii) {
+    pos[depth] = ii;
+    combinations_recursive(elems, req_len, pos, depth + 1, ii + 1, collection);
+  }
+  return;
+}
+
+
+///////////////////////////////////////////////
+// For locus l, main proxy association function
+
+void Plink::performProxyTests(int l)
+{
+  
+  // Consider a particular SNP, l, and 
+  // a) form haplotypes surrounding SNPs
+  // b) calculate association with phenotype for these SNPs
+  // c) calculate r^2 (haplotypic) with allele and haplotypes
+  
+  // Form haplotypes based on the surrounding SNPs
+  // Form phenotype based on the patterns of missingness for test SNP
+  // Is there any association?
+
+  bool old_silent = par::silent;
+
+  
+  ////////////////////////////////////////////////////////////////
+  // If we are in 'impute' mode: this is to evaluate imputation, in a
+  // 'leave-one-out' manner; here we assume the reference panel is
+  // coded as 'missing phenotype' and the rest of the sample is coded
+  // as non-missing phenotype; so we must first blank out (but later
+  // replace) any genotype data for these individuals
+
+  vector<bool> tmp1, tmp2;
+
+  if ( par::proxy_impute || par::proxy_leave_out ) 
+    {
+      
+      // Pretend that we do not have these genotypes, except for the
+      // reference panel (i.e. individuals with a missing phenotype)
+
+      for ( int i = 0 ; i < n ; i++ ) 
+	if ( ! sample[i]->missing )
+	  {
+	    tmp1.push_back( SNP[l]->one[i] );
+	    tmp2.push_back( SNP[l]->two[i] );
+	    
+	    SNP[l]->one[i] = true;
+	    SNP[l]->two[i] = false;
+	  }
+    }
+ 
+
+  ///////////////////////
+  // Form test haplotypes
+  
+  CSNP * s = SNP[l];
+  
+  vector<int> proxyHaplotypePlusSNP;
+
+
+  // Add reference SNP
+
+  proxyHaplotypePlusSNP.push_back(l);
+
+
+  // Either a fixed maximum number of SNPs left and right (allowing
+  // for different filters, and chromosome ends) or read from a file
+  // (these SNPs must be on same chromosome)
+  
+  if ( par::proxy_list )
+    {
+      checkFileExists( par::proxy_list_file );
+      printLOG("Reading proxy list from [ " 
+	       + par::proxy_list_file + " ]\n");
+      ifstream PL( par::proxy_list_file.c_str(), ios::in);
+      
+      map<string,int> mlocus;
+      for (int j=0;j<nl_all;j++)
+	mlocus.insert(make_pair(locus[j]->name,j));
+
+      while ( ! PL.eof() )
+	{
+	  string psnp;
+	  PL >> psnp;
+
+	  if ( psnp == "" )
+	    continue;
+	  
+	  map<string,int>::iterator m = mlocus.find( psnp );
+	  
+	  if ( m == mlocus.end() )
+	    continue;
+	  
+	  // Add if okay w/ MAF and genotyping thresholds
+	  
+	  int pn = m->second;
+	  
+	  if ( pn != l && 
+	       locus[pn]->chr == locus[l]->chr && 
+	       locus[pn]->freq >= par::proxy_maf && 
+	       abs(double((locus[l]->bp - locus[pn]->bp)/1000.0)) 
+	       <= par::proxy_kb &&
+	       locus[pn]->pos <= par::proxy_geno )
+	    {
+	      proxyHaplotypePlusSNP.push_back( pn );	      
+	    }
+	  
+	}
+
+      PL.close();
+    }
+  
+  else // ... use window approach
+    {
+      
+      int i = l-1;
+      int added = 0;
+      
+      while ( added < par::proxy_window )
+	{
+	  if ( i >= 0 && 
+	       locus[i]->chr == locus[l]->chr )
+	    {
+	      
+	      // Add MAF and genotyping thresholds here
+	      if ( locus[i]->freq >= par::proxy_maf && 
+		   abs(double((locus[l]->bp - locus[i]->bp)/1000.0)) 
+		   <= par::proxy_kb &&
+		   locus[i]->pos <= par::proxy_geno )
+		{
+		  proxyHaplotypePlusSNP.push_back(i);
+		  added++;
+		}
+	      
+	      // Shift left
+	      --i;
+	    }
+	  else
+	    {
+	      // Cannot add any more
+	      added = par::proxy_window;
+	    }
+	}
+      
+      // Now move right
+      added = 0;
+      i = l+1;
+      while ( added < par::proxy_window )
+	{
+	  if ( i < nl_all && 
+	       locus[i]->chr == locus[l]->chr )
+	    {
+	      
+	      // Add MAF, kb and genotyping thresholds here
+	      if ( locus[i]->freq >= par::proxy_maf && 
+		   abs(double((locus[l]->bp - locus[i]->bp)/1000.0)) 
+		   <= par::proxy_kb &&
+		   locus[i]->pos <= par::proxy_geno )
+		{
+		  proxyHaplotypePlusSNP.push_back(i);
+		  added++;
+		}
+	      
+	      //Shift right
+	      ++i;
+	    }
+	  else
+	    {
+	      // Cannot add any more
+	      added = par::proxy_window;
+	    }
+	  
+	}
+    }
+  
+  
+  ///////////////////////////////////////////////////////////////////////////
+  //
+  // Optionally, filter list based on LD with reference and with eachother
+  //
+  ///////////////////////////////////////////////////////////////////////////
+
+
+  if ( par::proxy_r2_filter ) 
+    {
+      
+      // Only use Reference Panel for these r-sq calculations at this stage; 
+      // add flag to modify this
+
+      if ( par::proxy_reference_only )
+	haplo->reference_only = true;
+      
+      set<int> added;
+
+      // Examine SNP number list: proxyHaplotypePlusSNP
+      // First entry is always the reference SNP
+
+      set<LDPair> proxies;
+      
+      // Skip first entry
+      for (int i=1; i<proxyHaplotypePlusSNP.size(); i++)
+	{
+	  LDPair p;
+	  p.s1 = l;
+	  p.s2 = proxyHaplotypePlusSNP[i];
+	  p.ld = haplo->rsq(p.s1,p.s2);
+	  //p.ld = haplo->dprime(p.s1,p.s2);
+
+	  proxies.insert(p);
+	}
+      
+      set<LDPair>::iterator pi = proxies.begin();
+
+      while ( pi != proxies.end() )
+	{
+	  
+	  // Enough proxies already?
+	  
+	  if ( added.size() >= par::proxy_snp_filter )
+	    break;
+	  
+	  if ( ( added.size() < 2 && pi->ld >= par::proxy_r2_filter_A ) // low filter
+	       || pi->ld >= par::proxy_r2_filter_B )  // higher filter, once 2 proxies found
+	    {
+	      
+	      // But does this already correlate too strongly with an
+	      // existing proxy?
+	      
+	      set<int>::iterator si = added.begin();
+	      
+	      bool okay = true;
+	      while ( si != added.end() )
+		{
+		  int2 snps;
+		  
+		  if ( snps.p1 > snps.p2 )
+		    {
+		      snps.p1 = *si;
+		      snps.p2 = pi->s2;
+		    }
+		  else
+		    {
+		      snps.p1 = pi->s2;
+		      snps.p2 = *si;
+ 		    }
+		  
+		  double ld;
+		  
+		  map<int2,double>::iterator f = proxyLD.find(snps); 
+		  if ( f != proxyLD.end() )
+		    {
+		      ld = f->second;
+		    }
+		  else
+		    {
+		      ld = haplo->rsq(snps.p1,snps.p2);
+		      //ld = haplo->dprime(snps.p1,snps.p2);
+		      proxyLD.insert(make_pair(snps,ld));
+		    }
+		  
+		  if ( ld > par::proxy_r2_filter_C )
+		    {
+		      okay = false;
+		      break;
+		    }
+		  ++si;
+		}
+	      
+	      if ( okay ) 
+		{
+		  added.insert( pi->s2 );
+		}
+	    }
+	  
+	  // Consider next proxy SNP
+	  ++pi;
+	}
+
+
+      //////////////////////////////////
+      // Update the fitlered proxy list
+      
+      proxyHaplotypePlusSNP.clear();
+      proxyHaplotypePlusSNP.push_back(l);
+      set<int>::iterator si = added.begin();
+      while ( si != added.end() )
+	{
+	  proxyHaplotypePlusSNP.push_back( *si );
+	  ++si;
+
+	}
+ 
+
+      // And remember to reset
+      haplo->reference_only = false;
+    }
+
+
+  //////////////////////////////////////////////////////////////////
+  //
+  // Sort, and select reference SNP
+  //
+  //////////////////////////////////////////////////////////////////
+
+  sort( proxyHaplotypePlusSNP.begin(), 
+	proxyHaplotypePlusSNP.end());
+
+  int cnt = proxyHaplotypePlusSNP.size();
+  int ref;
+
+  for (int i=0; i<cnt; i++)
+    if ( proxyHaplotypePlusSNP[i] == l )
+      {
+	ref = i;
+	break;
+      }
+
+
+  //////////////////////////////////////////////////////////////////////
+  //
+  // Do we actually have 1 or more proxy SNP selected? If not, leave now
+  // if in verbose mode
+  //
+  //////////////////////////////////////////////////////////////////////
+  
+  if ( par::proxy_all && ( ! par::proxy_full_report ) )
+    {
+      
+      if ( proxyHaplotypePlusSNP.size() == 1 )
+ 	{
+	  
+ 	  if ( ! par::proxy_impute )
+ 	    {
+ 	      haplo->HTEST << setw( 4 ) << locus[l]->chr << " " 
+ 			   << setw(par::pp_maxsnp) << locus[l]->name << " "
+ 			   << setw(12) << locus[l]->bp << " "
+ 			   << setw(4) << locus[l]->allele1 << " "
+ 			   << setw(4) << locus[l]->allele2 << " "
+ 			   << setw(10) << locus[l]->pos << " "
+ 			   << setw(4) << proxyHaplotypePlusSNP.size() - 1 << " "
+ 			   << setw(8) << "NA" << " ";
+	      
+ 	      // Display C/C or T/U for case/control and TDT, else F and BETA
+	      
+ 	      if ( par::qt || par::proxy_glm ) 
+ 		haplo->HTEST << setw(8) << "NA" << " "
+ 			     << setw(8) << "NA" << " ";	      
+ 	      else
+ 		haplo->HTEST << setw(8) << "NA" << " "
+ 			     << setw(8) << "NA" << " "
+ 			     << setw(8) << "NA" << " ";
+	      
+ 	      haplo->HTEST << setw(10) << "NA" << " ";
+	      
+ 	      if ( par::proxy_list_proxies )
+ 		haplo->HTEST << "(NONE)";
+	      
+ 	      haplo->HTEST << "\n";
+
+
+	      // Finally, replace any genotypes made temporarily missing
+
+	      if ( par::proxy_leave_out )
+		{
+		  int cnt = 0;
+		  for ( int i = 0 ; i < n ; i++ ) 
+		    if ( ! sample[i]->missing )
+		      {
+			SNP[l]->one[i] = tmp1[cnt];
+			SNP[l]->two[i] = tmp2[cnt++];
+		      }
+		  
+		  tmp1.clear();
+		  tmp2.clear();
+		}
+
+	      return;
+ 	    }
+
+ 	}
+     }
+
+  
+
+
+  ///////////////////////////////////////////////////////////////////////////////
+  //
+  // Phase haplotypes
+  //
+  ///////////////////////////////////////////////////////////////////////////////  
+
+  haplo->reset();
+
+  haplo->new_pred_locus.resize(1);
+
+  haplo->new_map.resize(1);
+
+  haplo->new_pred_locus[0] = proxyHaplotypePlusSNP;
+
+  haplo->new_map[0] = locus[l];
+
+  par::silent = true;
+
+  haplo->phaseAllHaplotypes();
+  
+  haplo->hname = locus[l]->name;
+  
+  par::silent = old_silent;
+
+
+
+  ///////////////////////////////////////////////////////////////////////////////
+  //
+  // Per-genotype error screen 
+  //
+  ///////////////////////////////////////////////////////////////////////////////
+
+  if ( par::proxy_error ) 
+    {
+
+      // Identify test SNP with respect to 0..cnt phased region
+      // (i.e. 'ref' and not 'l')
+      
+      haplo->queryGenotype( ref );
+      return;
+    }
+   
+ 
+  //////////////////////////////////////////////////////////////////////////////
+  //
+  // If we are in 'impute' mode: do not perform association tests, but
+  // just compare imputed genotypes to actual (left-out) genotypes,
+  // and report on this.
+  //
+  //////////////////////////////////////////////////////////////////////////////  
+
+  if ( par::proxy_leave_out )
+    {
+      int cnt = 0;
+      for ( int i = 0 ; i < n ; i++ ) 
+	if ( ! sample[i]->missing )
+	  {
+	    SNP[l]->one[i] = tmp1[cnt];
+	    SNP[l]->two[i] = tmp2[cnt++];
+	  }
+
+      tmp1.clear();
+      tmp2.clear();
+    }
+  else if ( par::proxy_impute ) 
+    {
+      
+      ////////////////////////////////////////
+      // Replace genotypes, and record dosage
+      
+      // For imputation quality score
+      boolvec_t m1(cnt,false);
+      m1[ref] = true;
+      boolvec_t a1(cnt,false);
+      map<int,int> tests = haplo->makeTestSet(m1,a1);
+      set<int> hs;
+      map<int,int>::iterator i1 = tests.begin();
+      while ( i1 != tests.end() )
+	{
+	  if ( i1->second == 0 )
+	    hs.insert( i1->first);
+	  ++i1;
+	}
+
+      haplo->calculateEmpiricalVariance(hs);
+    
+
+      int con[4][4];
+      for (int j=0;j<4;j++)
+	for (int k=0; k<4; k++)
+	  con[j][k] = 0; 
+      
+
+      if ( par::proxy_record_dosage )
+	OUTFILE << locus[l]->name << "\t"
+		<< locus[l]->allele1 << "\t"
+		<< locus[l]->allele2 << "\t"
+		<< haplo->ratio << "\t";
+
+      int cnt = 0;
+      for ( int i = 0 ; i < n ; i++ ) 
+	if ( ! sample[i]->missing )
+	  {
+	    
+	    // Actual genotypes
+
+	    bool a1 = tmp1[cnt];
+	    bool a2 = tmp2[cnt++];
+
+	    int og;
+
+	    if ( a1 )
+	      {
+		if ( a2 ) 
+		  og = 2;
+		else
+		  og = 3;
+	      }
+	    else
+	      {
+		if ( a2 ) 
+		  og = 1;
+		else
+		  og = 0;
+	      }
+	    
+	    // Imputed genotypes
+
+	    vector_t g = haplo->imputeGenotype(i,ref);
+
+	    // Call imputed
+
+	    bool i1, i2;
+
+	    if ( g[0] > par::proxy_impute_threshold ) 
+	      {
+		i1 = i2 = false;
+		con[og][0]++;
+	      }
+	    else if ( g[1] > par::proxy_impute_threshold ) 
+	      { 
+		i1 = false; 
+		i2 = true; 
+		con[og][1]++;
+	      }
+	    else if ( g[2] > par::proxy_impute_threshold ) 
+	      {
+		i1 = i2 = true;
+		con[og][2]++;
+	      }
+	    else 
+	      { 
+		i1 = true; i2 = false; 
+		con[og][3]++;
+	      }
+
+	    if ( par::proxy_full_report ) 
+	      haplo->HTEST << locus[l]->name << "\t" 
+			   << sample[i]->fid << " " 
+			   << sample[i]->iid << "\t" 
+			   << a1<<a2 << " " 
+			   << i1<<i2 << " " 
+			   << g[0] << " " 
+			   << g[1] << " " 
+			   << g[2] << "\n";
+	    
+	    if ( par::proxy_record_dosage )
+	      OUTFILE << g[0] + 0.5 * g[1] << "\t";
+	    
+	    
+	    ////////////////////////////////////////////////
+	    // Replace missing slots with imputed genotypes
+	    
+	    // Note: because genotyping rate is pre-calculated, this 
+	    // will not be a problem in practice (as long as panel is 
+	    // sufficiently large) -- i.e. in smaller cases, we need 
+	    // to worry about whether this imputed SNP now might be 
+	    // used as a proxy for another SNP -- wouldn't be terrible, 
+	    // but probably better to try to use real SNPs as 
+	    // proxies whenever possible.
+
+//  	    if ( ! par::proxy_impute_preserve_genotyped ) 
+// 	      {
+		if ( par::proxy_impute_replace || ( a1 && ! a2 ) ) 
+		  {
+		    SNP[l]->one[i] = i1;
+		    SNP[l]->two[i] = i2;
+		  }
+		else
+		  {
+		    SNP[l]->one[i] = a1;
+		    SNP[l]->two[i] = a2;		
+		  }
+//	      }
+	  }
+
+
+      if ( par::proxy_record_dosage )
+	OUTFILE << "\n";
+
+      // Report matrix of concordance
+
+      int total = 0;
+      for (int j=0;j<4;j++)
+	for (int k=0;k<4;k++)
+	  total += con[j][k];
+
+      int concordant = con[0][0] + con[1][1] + con[2][2];
+
+      int both_geno = 0;
+      for (int j=0;j<3;j++)
+	for (int k=0;k<3;k++)
+	  both_geno += con[j][k];
+      
+      int observed_geno = total;
+      for (int j=0; j<4; j++)
+	observed_geno -= con[3][j];
+      
+      int imputed_geno = total;
+      for (int j=0; j<4; j++)
+	imputed_geno -= con[j][3];
+      
+      double rate = both_geno == 0 ? 
+	-1 : 
+	(double)concordant/(double)both_geno ;
+      
+      double rate_obs = (double)observed_geno/(double)total;
+      double rate_imp = (double)imputed_geno/(double)total;
+      double rate_ovr = (double)both_geno/(double)total;
+            
+      if ( par::proxy_full_report ) 
+	{
+	  haplo->HTEST << "\nImputation matrix "
+		       << "(rows observed, columns imputed)\n\n";
+	  
+	  for (int j=0;j<4;j++)
+	    {
+	      
+	      if ( j == 0 ) 
+		haplo->HTEST << locus[l]->allele1 << "/"
+			     << locus[l]->allele1 << "\t";
+	      else if ( j == 1 ) 
+		haplo->HTEST << locus[l]->allele1 << "/"
+			     << locus[l]->allele2 << "\t";
+	      else if ( j == 2 ) 
+		haplo->HTEST << locus[l]->allele2 << "/"
+			     << locus[l]->allele2 << "\t";
+	      else
+		haplo->HTEST << par::missing_genotype << "/"
+			     << par::missing_genotype << "\t";	  
+	      
+	      for (int k=0; k<4; k++)
+		haplo->HTEST << con[j][k] << "\t";
+	      
+	      haplo->HTEST << "\n";
+	      
+	    }
+	  
+	  haplo->HTEST << setw(4) << "CHR" << " " 
+		       << setw(par::pp_maxsnp) << "SNP" << " "
+		       << setw(8) << "INFO" << " " 
+		       << setw(4) << "NPRX" << " "
+		       << setw(8) << "TOTAL_N" << " "
+		       << setw(8) << "OBSERVD" << " "
+		       << setw(8) << "IMPUTED" << " "
+		       << setw(8) << "OVERLAP" << " "
+		       << setw(8) << "CONCORD" << " ";
+	  
+	  if ( par::proxy_impute_genotypic_concordance )
+	    haplo->HTEST << setw(8) << "F_AA" << " "
+			 << setw(8) << "I_AA" << " "
+			 << setw(8) << "C_AA" << " "
+			 << setw(8) << "F_AB" << " "
+			 << setw(8) << "I_AB" << " "
+			 << setw(8) << "C_AB" << " "
+			 << setw(8) << "F_BB" << " "
+			 << setw(8) << "I_BB" << " "
+			 << setw(8) << "C_BB" << " ";
+	  
+	  if ( par::proxy_list_proxies )
+	    haplo->HTEST << "SNPS";
+
+	  haplo->HTEST << "\n";
+	  
+	}
+
+            
+      haplo->HTEST << setw(4) << locus[l]->chr << " " 
+		   << setw(par::pp_maxsnp) << locus[l]->name << " "
+		   << setw(4) << proxyHaplotypePlusSNP.size() - 1 << " "
+		   << setw(8) << haplo->ratio << " " 
+		   << setw(8) << total << " "
+		   << setw(8) << rate_obs << " "
+		   << setw(8) << rate_imp << " "
+		   << setw(8) << rate_ovr << " ";
+
+      if ( rate >= 0 )
+	haplo->HTEST << setw(8) <<  rate << " ";
+      else
+	haplo->HTEST << setw(8) << "NA" << " ";
+
+      if ( par::proxy_impute_genotypic_concordance )
+	{
+
+	  int impAA = con[0][0]+con[0][1]+con[0][2];
+	  int impAB = con[1][0]+con[1][1]+con[1][2];
+	  int impBB = con[2][0]+con[2][1]+con[2][2];
+	  
+	  double fAA = (double)(con[0][0]+con[1][0]+con[2][0]) / (double)observed_geno;
+	  double fAB = (double)(con[0][1]+con[1][1]+con[2][1]) / (double)observed_geno;
+	  double fBB = (double)(con[0][2]+con[1][2]+con[2][2]) / (double)observed_geno;
+	  
+	  if ( observed_geno == 0 ) 
+	    fAA = fAB = fBB = 0;
+	  
+	  int obsAA = impAA+con[0][3];
+	  int obsAB = impAB+con[1][3];
+	  int obsBB = impBB+con[2][3];
+
+	  haplo->HTEST << setw(8) << fAA << " ";
+
+	  if ( obsAA == 0 ) 
+	    haplo->HTEST << setw(8) << "NA" << " ";
+	  else
+	    haplo->HTEST << setw(8) << (double)(impAA)/(double)(impAA+con[0][3]) << " ";	  
+
+	  if ( impAA==0 )
+	    haplo->HTEST << setw(8) << "NA" << " ";
+	  else
+	    haplo->HTEST << setw(8) << (double)(con[0][0])/(double)impAA << " ";
+	  
+	  haplo->HTEST << setw(8) << fAB << " ";
+	  if ( obsAB == 0 ) 
+	    haplo->HTEST << setw(8) << "NA" << " ";
+	  else
+	  haplo->HTEST << setw(8) << (double)(impAB)/(double)(impAB+con[1][3]) << " ";
+	  if ( impAB==0 )
+	    haplo->HTEST << setw(8) << "NA" << " ";
+	  else
+	    haplo->HTEST << setw(8) << (double)(con[1][1])/(double)impAB << " ";
+
+	  haplo->HTEST << setw(8) << fBB << " ";
+	  if ( obsBB == 0 ) 
+	    haplo->HTEST << setw(8) << "NA" << " ";
+	  else
+	  haplo->HTEST << setw(8) << (double)(impBB)/(double)(impBB+con[2][3]) << " ";
+	  if ( impBB==0 )
+	    haplo->HTEST << setw(8) << "NA" << " ";
+	  else
+	    haplo->HTEST << setw(8) << (double)(con[2][2])/(double)impBB << " ";
+	  
+	}
+
+      
+      if ( par::proxy_list_proxies )
+	{
+	  bool printed = false;
+	  for (int l0=0; l0< proxyHaplotypePlusSNP.size(); l0++)
+	    {
+	      if ( proxyHaplotypePlusSNP[ l0 ] != l ) 
+		{
+		  if ( printed ) 
+		    haplo->HTEST << "|";		  
+		  haplo->HTEST << locus[ proxyHaplotypePlusSNP[ l0 ] ]->name;
+		  printed = true;
+		  
+		}
+	    }
+	}
+      
+      
+      haplo->HTEST << endl;
+      
+      tmp1.clear();
+      tmp2.clear();
+      
+      return;
+    }
+
+
+
+
+  ////////////////////////////////////////////////////////////////
+  //                                                            //
+  // Consider all subsets of subhaplotypes, if in verbose mode  //
+  //                                                            //
+  ////////////////////////////////////////////////////////////////
+
+  
+  if ( ! ( par::proxy_all || par::proxy_full_report ) )
+    printLOG("Estimated haplotype frequencies: now considering combinations...\n");
+
+
+
+
+  ////////////////////////////////////////////////////
+  // Display haplotype frequencies and individual r^2
+
+  if ( ( ! par::proxy_all ) || par::proxy_full_report )
+    haplo->HTEST << "\n"
+		 << "     *** Proxy haplotype association report for " 
+		 << haplo->hname << " *** \n\n";
+  
+
+  ////////////////////////////////////////
+  // Report SNPs and single-SNP r-squared
+	    
+  if ( ( ! par::proxy_all) || par::proxy_full_report )
+    {
+      haplo->HTEST << setw(par::pp_maxsnp) << "SNP" << " " 
+		   << setw(8) << "MAF" << " " 
+		   << setw(8) << "GENO" << " "
+		   << setw(8) << "KB" << " "
+		   << setw(8) << "RSQ" << " ";
+      if ( par::qt ) 
+	haplo->HTEST << setw(8) << "BETA" << " "
+		     << setw(8) << "STAT" << " "	  
+		     << setw(8) << "P" << "\n";
+      else 
+	haplo->HTEST << setw(8) << "OR" << " "
+		     << setw(8) << "CHISQ" << " "	  
+		     << setw(8) << "P" << "\n";
+
+
+      for ( int s = 0 ; s < cnt ; s++)
+	{	  
+	  haplo->HTEST << setw(par::pp_maxsnp) 
+		       << locus[ haplo->new_pred_locus[0][s] ]->name << " "
+		       << setw(8) 
+		       << locus[ haplo->new_pred_locus[0][s] ]->freq << " "
+		       << setw(8) 
+		       << locus[ haplo->new_pred_locus[0][s] ]->pos  << " "
+		       << setw(8) 
+		       << (double)(locus[ haplo->new_pred_locus[0][s]]->bp - 
+				   locus[ haplo->new_pred_locus[0][ref]]->bp)/1000<<" ";
+	  
+	  // R-squared
+
+	  if ( s == ref ) 
+	    haplo->HTEST << setw(8) << "*" << " ";
+	  else
+	    haplo->HTEST << setw(8) << haplo->rsq_internal(s,ref) << " ";
+
+	  // Single SNP association
+
+	  boolvec_t snpmask(cnt,false);
+	  boolvec_t dummy_allele(cnt,true);
+	  snpmask[s] = true;
+	  
+	  haplo->testSet = haplo->makeTestSet(snpmask,dummy_allele);
+
+	  if (par::proxy_CC)
+	    {
+	      // GLM or standard test?
+	      if ( par::proxy_glm )
+		{
+		  glmAssoc(false,*pperm);
+		}
+	      else
+		{		   
+		  if ( par::qt )
+		    haplo->haplotypicQTL(haplo->testSet,2,false);
+		  else
+		    haplo->haplotypicCC(haplo->testSet,2,false);
+		}
+	    }
+	  else if (par::proxy_TDT)
+	    {
+	      
+	      haplo->subhaplotypes = true;
+	      haplo->downcoding = haplo->testSet;
+	      
+	      haplo->trans.clear();
+	      haplo->untrans.clear();
+	      
+	      haplo->trans.resize(2,0);
+	      haplo->untrans.resize(2,0);
+	      haplo->nt = 2;
+
+	      // First rescore transmissions
+	      
+	      for (int i=0; i<n; i++)
+		{
+		  if ( (!sample[i]->founder) && 
+		       haplo->include[i] )
+		    {		      
+		      haplo->transmissionCount(i,haplo->phasemap[i]);
+		    }
+		}
+	      
+
+	      // Then recount T:U based on revised transmission counts
+	      
+	      haplo->haplotypicTDT(haplo->testSet,2,false);
+	      
+	      haplo->subhaplotypes = false;
+	      haplo->downcoding.clear();
+	      
+	    }
+	  
+	  // Recover main results from Model, if GLM used
+	  if ( par::proxy_glm )
+	    {
+	      vector_t coef = model->getCoefs();
+	      haplo->odds = par::bt ? exp(coef[1]) : coef[1];
+	      haplo->result = model->isValid() ? model->getStatistic() : 0;
+	      haplo->pvalue = par::bt ? chiprobP(haplo->result,1) : ((LinearModel*)model)->getPValue();
+	      delete model;
+	    }
+
+	  haplo->HTEST << setw(8) << haplo->odds << " "
+		       << setw(8) << haplo->result << " "
+		       << setw(8) << haplo->pvalue << "\n";
+	  
+	}
+
+      haplo->HTEST << "\n\n";
+    }
+
+  
+  ///////////////////////////////////////////////////
+  // Report haplotypes and frequencies, and also all
+  // haplotype-specific tests and omnibus test result
+  
+  if ( ( ! par::proxy_all ) || par::proxy_full_report )
+    {
+      string str = "";
+      for ( int i = 0; i < cnt ; i++)
+	if ( i == ref ) 
+	  str += "*";
+	else
+	  str += ".";
+      
+      haplo->HTEST << setw(14) << str << " "
+		   << setw(10) << "FREQ" << " ";
+      if ( par::qt ) 
+	haplo->HTEST << setw(8) << "BETA" << " "
+		     << setw(8) << "STAT" << " "	  
+		     << setw(8) << "P" << "\n";
+      else 
+	haplo->HTEST << setw(10) << "OR" << " "
+		     << setw(10) << "CHISQ" << " " 
+		     << setw(10) << "P" << "\n";
+
+      for (int h=0; h< haplo->nh; h++)      
+	{
+	  if (haplo->f[h] >= par::proxy_mhf )
+	    {	  
+	      haplo->HTEST << setw(14) << haplo->haplotypeName(h) << " " 
+			   << setw(10) << haplo->f[h] << " ";
+	      
+
+	      haplo->testSet.clear();
+	      
+	      for (int h2=0; h2 < haplo->nh; h2++)
+		{
+		  if ( haplo->f[h2] >= par::proxy_mhf)
+		    {
+		      if (h==h2) 
+			{
+			  haplo->testSet.insert(make_pair(h2,0));
+			}
+		      else 
+			{
+			  haplo->testSet.insert(make_pair(h2,1));
+			}
+		    }
+		}
+
+	      if (par::proxy_CC)      
+		{
+		  // GLM or standard test?
+		  if ( par::proxy_glm )
+		    {
+		      glmAssoc(false,*pperm);
+		    }
+		  else
+		    {		   
+		      
+		      if ( par::qt)
+			haplo->haplotypicQTL(haplo->testSet,2,false);		
+		      else
+			haplo->haplotypicCC(haplo->testSet,2,false);		
+		    }
+		}
+	      else if (par::proxy_TDT)
+		{
+
+		  haplo->subhaplotypes = true;
+		  haplo->downcoding = haplo->testSet;
+		  
+		  haplo->trans.clear();
+		  haplo->untrans.clear();
+		  
+		  haplo->trans.resize(2,0);
+		  haplo->untrans.resize(2,0);
+		  haplo->nt = 2;
+
+		  // First rescore transmissions
+		  
+		  for (int i=0; i<n; i++)
+		    {
+		      if ( (!sample[i]->founder) && 
+			   haplo->include[i] )
+			{		      
+			  haplo->transmissionCount(i,haplo->phasemap[i]);
+			}
+		    }
+		  
+		  // Then recount T:U based on revised transmission counts
+		  
+		  haplo->haplotypicTDT(haplo->testSet,2,false);
+		  
+		  haplo->subhaplotypes = false;
+		  haplo->downcoding.clear();
+		  
+		  
+		}
+	      
+	      // Recover main results from Model, if GLM used
+	      if ( par::proxy_glm )
+		{
+		  vector_t coef = model->getCoefs();
+		  haplo->odds = par::bt ? exp(coef[1]) : coef[1];
+		  haplo->result = model->isValid() ? model->getStatistic() : 0;
+		  haplo->pvalue = par::bt ? chiprobP(haplo->result,1) : ((LinearModel*)model)->getPValue();
+		  delete model;
+		}	      
+	      
+	      haplo->HTEST << setw(10) << haplo->odds << " "
+			   << setw(10) << haplo->result << " "
+			   << setw(10) << haplo->pvalue << "\n";
+	      
+	    }
+	}
+
+
+      haplo->HTEST << "\nHaplotype frequency estimation based on " 
+		   << haplo->validN; 
+
+      if ( haplo->X ) 
+	{
+	  int found_chr = 0;
+	  for (int i=0; i<n; i++)
+	    if ( sample[i]->founder )
+	      {
+		if ( sample[i]->sex )
+		  found_chr++;
+		else
+		  found_chr+=2;
+	      }
+	  haplo->HTEST << " of " << found_chr << " founder chromosomes\n";
+	}
+      else if ( haplo->haploid )
+	haplo->HTEST << " of " << haplo->cnt_f << " founder chromosomes\n";
+      else
+	haplo->HTEST << " of " << haplo->cnt_f * 2 << " founder chromosomes\n";
+
+		   
+
+      ///////////////////////////////////
+      // Omnibus test: C/C only
+
+      if ( par::proxy_CC && ! par::qt )
+	{
+	   
+	  map<int,int> tests;
+	  int nch=0;
+	  for (int h=0; h < haplo->nh; h++)
+	    if ( haplo->f[h] >= par::proxy_mhf)
+	      tests.insert(make_pair(h,nch++));
+	  
+	  if (nch>2)
+	    {
+	      haplo->haplotypicCC(tests,nch,false);
+	      
+	      haplo->HTEST << "Omnibus haplotype test statistic: " 
+			   << haplo->result << ", df = " << nch-1 << ", "
+			   << "p = " 
+			   << chiprobP( haplo->result , nch-1 ) << "\n\n";
+	    }
+	  
+	} 
+    }
+
+
+
+  ///////////////////////////////////////////
+  // Create masks
+
+  // Reference SNP (fix here)
+  boolvec_t m1(cnt,false);
+  m1[ref] = true;
+  boolvec_t a1(cnt,true);
+
+  // Proxy haplotype (populated below)
+  boolvec_t m2(cnt,false);
+  boolvec_t a2(cnt); 
+  
+
+  ///////////////////////////////////////////
+  //         Report actual SNP             //
+  ///////////////////////////////////////////
+
+  haplo->testSet = haplo->makeTestSet(m1,a1);
+  
+  if (par::proxy_CC)
+    {
+      // GLM or standard test?
+      if ( par::proxy_glm )
+	{
+	  glmAssoc(false,*pperm);
+	}
+      else
+	{		   	  
+	  if ( par::qt )
+	    haplo->haplotypicQTL(haplo->testSet,2,false);
+	  else
+	    haplo->haplotypicCC(haplo->testSet,2,false);
+	}
+    }
+  else if (par::proxy_TDT)
+    {      
+
+      haplo->subhaplotypes = true;
+      haplo->downcoding = haplo->testSet;
+      
+      haplo->trans.clear();
+      haplo->untrans.clear();
+      
+      haplo->trans.resize(2,0);
+      haplo->untrans.resize(2,0);
+      haplo->nt = 2;
+
+      // First rescore transmissions
+      
+      for (int i=0; i<n; i++)
+	{
+	  if ( (!sample[i]->founder) && 
+	       haplo->include[i] )
+	    {		      
+	      haplo->transmissionCount(i,haplo->phasemap[i]);
+	    }
+	}
+
+    
+      // Then recount T:U based on revised transmission counts
+      
+      haplo->haplotypicTDT(haplo->testSet,2,false);
+      
+      haplo->subhaplotypes = false;
+      haplo->downcoding.clear();
+     
+      // Also, calculate the information score
+      set<int> t1 = haplo->makeSetFromMap(haplo->testSet);
+      haplo->calculateEmpiricalVariance(t1);
+
+    }
+  
+  
+  // Recover main results from Model, if GLM used
+  if ( par::proxy_glm )
+    {
+      vector_t coef = model->getCoefs();
+      haplo->odds = par::bt ? exp(coef[1]) : coef[1];
+      haplo->result = model->isValid() ? model->getStatistic() : 0;
+      haplo->pvalue = par::bt ? chiprobP(haplo->result,1) : ((LinearModel*)model)->getPValue();
+      delete model;
+      
+      // Also, calculate the information score
+      set<int> t1 = haplo->makeSetFromMap(haplo->testSet);
+      haplo->calculateEmpiricalVariance(t1);
+    }
+  
+
+  //////////////////////////////////////////////////////////////////////
+  //
+  // Just report the single SNP result (based on haplotype test)?
+  //
+  //////////////////////////////////////////////////////////////////////
+
+  if ( par::proxy_all && ( ! par::proxy_full_report ) )
+    {
+
+      
+      
+      haplo->HTEST << setw( 4 ) << locus[l]->chr << " " 
+		   << setw(par::pp_maxsnp) << locus[l]->name << " "
+		   << setw(12) << locus[l]->bp << " "
+		   << setw(4) << locus[l]->allele1 << " "
+		   << setw(4) << locus[l]->allele2 << " "
+		   << setw(10) << locus[l]->pos << " " 
+		   << setw(4) << proxyHaplotypePlusSNP.size() - 1 << " "
+		   << setw(8) << haplo->ratio << " ";
+
+      // Display C/C or T/U for case/control and TDT, else F and BETA
+
+      if ( haplo->pvalue < -1 ) 
+	{
+	  // Not a valid test, e.g. monomorphic, and so p value is returned as -9
+	  if ( par::qt || par::proxy_glm ) 
+	    haplo->HTEST << setw(8) << "NA" << " "
+			 << setw(8) << "NA" << " "
+			 << setw(8) << "NA" << " ";
+	  else
+	    haplo->HTEST << setw(8) << "NA" << " "
+			 << setw(8) << "NA" << " "
+			 << setw(8) << "NA" << " "
+			 << setw(8) << "NA" << " ";	    	  
+	}
+      else
+	{
+      
+	  if ( par::qt || par::proxy_glm ) 
+	    {
+	      // Get population haplotype frequency for imputed SNP
+	      double f = haplo->freq(m1,a1);
+	      
+	      haplo->HTEST << setw(8) << f << " "
+			   << setw(8) << haplo->odds << " ";
+	    }
+	  else
+	    haplo->HTEST << setw(8) << haplo->case_freq << " "
+			 << setw(8) << haplo->control_freq << " "
+			 << setw(8) << haplo->odds << " ";
+	  
+	  haplo->HTEST << setw(10) << haplo->pvalue << " ";
+	}
+      
+      
+      if ( par::proxy_list_proxies )
+	{
+	  bool printed = false;
+	  for (int l0=0; l0< proxyHaplotypePlusSNP.size(); l0++)
+	    {
+	      if ( proxyHaplotypePlusSNP[ l0 ] != l ) 
+		{
+		  if ( printed )
+		    haplo->HTEST << "|";				  
+		  haplo->HTEST << locus[ proxyHaplotypePlusSNP[ l0 ] ]->name;
+		  printed = true;
+ 		}
+	    }
+	}
+
+
+      haplo->HTEST << endl;
+      
+      return;
+    }
+
+
+  
+
+
+
+  ////////////////////////////////////////////////////////////////////////
+  //
+  // Rest of this function is for the extended report mode  
+  //
+  ////////////////////////////////////////////////////////////////////////        
+
+
+
+  ///////////////////////////////////////////
+  // Consider from cnt-1 to 1 SNP haplotypes
+
+  int search_cnt = par::proxy_include_reference ? cnt : cnt - 1;
+  int maxsnp = search_cnt < par::proxy_maxhap ? search_cnt : par::proxy_maxhap;
+  
+  int num_subhaps_total = 0;
+  int num_subhaps_valid = 0;
+
+  set<ProxyResult> presults;
+  
+  for (int i=1; i<=maxsnp; i++)
+    {
+
+      // For an i-SNP of cnt-SNP, consider all the permutations
+
+      vector<unsigned long> pos1(i);
+      vector<int> d(search_cnt);
+      int i2=0;
+      for (int z=0; z<cnt; z++) 
+	if ( z != ref ) 
+	  {
+	    d[i2]=i2;
+	    i2++;
+	  }
+
+      vector<vector<int> > collection;
+      combinations_recursive(d,i,pos1,0,0,collection);
+
+      vector<int> mapback;
+      for (int s=0;s<cnt;s++)
+	if ( par::proxy_include_reference || s != ref )
+	  mapback.push_back(s);
+      
+      // Consider each combination of i of cnt-1 SNP haplotypes
+      // then consider each possible haplotype within that
+      
+      for (int c1 = 0; c1 < collection.size() ; c1++ )
+	{
+	  
+	  // For biallelic haplotypes (SNPs)
+	  // skip the second allele
+	  
+	  // Which SNPs do we want to look up?
+	  
+	  vector<int> posit = collection[c1];
+	  
+	  // Now consider all search_cnt SNP haplotypes 
+	  // i.e. excluding reference SNP
+	  
+	  int hapcnt = (int)pow((double)2,i);
+	  int h = 0;
+	  while ( h < hapcnt )
+	    {
+	      
+	      // Skip redundant second allele of 
+	      // SNPs
+
+	      if ( collection[c1].size() == 1 && 
+		   h == 1 )
+		{
+		  h++;
+		  continue;
+		}
+	      
+	      
+	      vector<bool> tmp;
+	      unsigned int p=1;
+	      for (int s=0;s<i;s++)
+		{
+		  if ( h & p ) tmp.push_back(false);
+		  else tmp.push_back(true);
+		  p <<= 1;
+		}
+	      
+	      
+	      ///////////////////////
+	      // Set proxy haplotype
+	      
+	      // Insert i-SNP haplotype back into 
+	      // full cnt-SNP space
+	      
+	      fill(m2.begin(), m2.end(), false);
+	      
+	      int t1=0;
+	      for (int t2=0; t2<i; t2++)
+		{
+		  m2[ mapback[ posit[t2] ] ] = true;
+		  a2[ mapback[ posit[t2] ] ] = tmp[ t2 ];
+		}
+	      
+	      
+	      ////////////////////////////////
+	      // Check frequency of haplotype
+	      
+	      double f = haplo->freq(m2,a2);
+	      
+	      
+	      ////////////////////////////////////////////////////////////
+	      // Calculate r^2 between haplotype and reference SNP allele
+	      
+	      double r2 = haplo->rsq_internal(m1,a1,m2,a2);
+	     
+
+	      	      
+	      ////////////////////////////////////////////
+	      // Is this haplotype not worth considering?
+	     
+
+	      ++num_subhaps_total;
+ 
+ 	      if ( r2 < par::proxy_r2 ||
+		   f < par::proxy_mhf )
+ 		{		  
+ 		  h++;
+ 		  continue;
+		}
+
+
+	      ++num_subhaps_valid;
+ 
+
+	      ////////////////////////////////////////////////////////////
+	      // Calculte association between proxy haplotype and disease
+	      
+	      // If only two haplotypes, report only 1
+	      // (note may only be two *common* haplotypes, but
+	      // in that case, we should report both
+	      
+	      haplo->testSet = haplo->makeTestSet(m2,a2);
+		      
+	      if (par::proxy_CC)
+		{
+		  // GLM or standard test?
+		  if ( par::proxy_glm )
+		    {
+		      glmAssoc(false,*pperm);
+		    }
+		  else
+		    {		   
+		      if ( par::qt )
+			haplo->haplotypicQTL(haplo->testSet,2,false);
+		      else
+			haplo->haplotypicCC(haplo->testSet,2,false);
+		    }
+		}
+	      else if (par::proxy_TDT)
+ 		{
+
+		  haplo->subhaplotypes = true;
+		  haplo->downcoding = haplo->testSet;
+		  
+		  haplo->trans.clear();
+		  haplo->untrans.clear();
+		  
+		  haplo->trans.resize(2,0);
+		  haplo->untrans.resize(2,0);
+		  haplo->nt = 2;
+		  
+		  // First rescore transmissions
+		  
+		  for (int i=0; i<n; i++)
+		    {
+		      if ( (!sample[i]->founder) && 
+			   haplo->include[i] )
+			{		      
+			  haplo->transmissionCount(i,haplo->phasemap[i]);
+			}
+		    }
+		  
+		  // Then recount T:U based on revised transmission counts
+		  
+		  haplo->haplotypicTDT(haplo->testSet,2,false);
+		  
+		  haplo->subhaplotypes = false;
+		  haplo->downcoding.clear();
+		}
+	      
+	      string str = par::proxy_include_reference ? 
+		haplo->getSubHaplotypeName(m2,a2,-1) :
+		haplo->getSubHaplotypeName(m2,a2,ref);
+	      
+
+	      // Recover main results from Model, if GLM used
+	      if ( par::proxy_glm )
+		{
+		  vector_t coef = model->getCoefs();
+		  haplo->odds = par::bt ? exp(coef[1]) : coef[1];
+		  haplo->result = model->isValid() ? model->getStatistic() : 0;
+		  haplo->pvalue = par::bt ? chiprobP(haplo->result,1) : ((LinearModel*)model)->getPValue();
+		  delete model;
+		}
+	      
+	      
+	      //////////////////////
+	      // Store this result
+
+	      ProxyResult r(str,f,r2,
+			    haplo->odds,
+			    haplo->result,
+			    haplo->pvalue);
+	      presults.insert(r);
+	      
+	      // Consider next haplotype
+	      
+	      h++;
+	      
+	    }
+	}      
+    }
+  
+
+  haplo->HTEST << "Of " << num_subhaps_total << " subhaplotypes considered, " 
+	       << num_subhaps_valid << " met proxy criteria\n\n";
+  
+  // Report results
+
+  if ( presults.size() == 0 )
+    haplo->HTEST << "No proxies found above r-sq " << par::proxy_r2 << "\n";
+  else
+    {
+      
+      haplo->HTEST << setw(14) << "HAP" << " "
+		   << setw(10) << "FREQ" << " " 
+		   << setw(10) << "RSQ" << " ";
+      if ( par::qt ) 
+	haplo->HTEST << setw(8) << "BETA" << " "
+		     << setw(8) << "STAT" << " "	  
+		     << setw(8) << "P" << "\n";
+      else 
+	haplo->HTEST << setw(10) << "OR" << " "
+		     << setw(10) << "CHISQ" << " "
+		     << setw(10) << "P" << "\n";
+      
+      
+      set<ProxyResult>::iterator i = presults.begin();
+      
+      while ( i != presults.end() )
+	{
+	  haplo->HTEST << setw(14) << i->name << " "
+		       << setw(10) << i->f << " " 
+		       << setw(10) << i->r2 << " " 
+		       << setw(10) << i->odds << " " 
+		       << setw(10) << i->chisq << " " 
+		       << setw(10) << i->pvalue << "\n";
+	  i++;
+	}
+    }
+
+  if ( par::proxy_full_report ) 
+    haplo->HTEST << "\n+--------------------------------------------------------------------+\n\n";
+
+  return;
+    
+}
+
+

Modified: trunk/packages/plink/trunk/Makefile
===================================================================
--- trunk/packages/plink/trunk/Makefile	2008-04-09 09:42:57 UTC (rev 1724)
+++ trunk/packages/plink/trunk/Makefile	2008-04-09 09:43:11 UTC (rev 1725)
@@ -17,12 +17,12 @@
 SYS = UNIX
 
 # Leave blank after "=" to disable; put "= 1" to enable
-WITH_R_PLUGINS = 1
+WITH_R_PLUGINS = 
 WITH_WEBCHECK = 1
 FORCE_32BIT = 
 
 # Put C++ compiler here; Windows has it's own specific version
-CXX_UNIX = g++
+CXX_UNIX = g++-3.3
 CXX_WIN = c:\bin\mingw\bin\mingw32-g++.exe
 
 # Any other compiler flags here ( -Wall, -g, etc)
@@ -43,7 +43,7 @@
 endif
 
 ifeq ($(SYS),UNIX)
- CXXFLAGS += -DUNIX -static
+ CXXFLAGS += -DUNIX
  CXX = $(CXX_UNIX)
 endif
 
@@ -115,3 +115,6 @@
 
 clean:
 	rm -f *.o *~
+
+distclean: clean
+	rm -f plink

Modified: trunk/packages/plink/trunk/clumpld.cpp
===================================================================
--- trunk/packages/plink/trunk/clumpld.cpp	2008-04-09 09:42:57 UTC (rev 1724)
+++ trunk/packages/plink/trunk/clumpld.cpp	2008-04-09 09:43:11 UTC (rev 1725)
@@ -11,6 +11,7 @@
 //////////////////////////////////////////////////////////////////
 
 
+#include <algorithm>
 #include <iostream>
 #include <iomanip>
 #include <fstream>


Property changes on: trunk/packages/plink/trunk/debian
___________________________________________________________________
Name: mergeWithUpstream
   + 1

Added: trunk/packages/plink/trunk/debian/README.Debian
===================================================================
--- trunk/packages/plink/trunk/debian/README.Debian	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/README.Debian	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,6 @@
+plink for Debian
+----------------
+
+Some more thoughts should be donated to the R plugin.
+
+ -- Steffen Moeller <moeller at debian.org>  Tue, 08 Apr 2008 17:49:32 +0200

Added: trunk/packages/plink/trunk/debian/changelog
===================================================================
--- trunk/packages/plink/trunk/debian/changelog	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/changelog	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,6 @@
+plink (1.02-1) unstable; urgency=low
+
+  * Initial release (Closes: #nnnn).
+
+ -- Steffen Moeller <moeller at debian.org>  Tue, 08 Apr 2008 17:49:32 +0200
+

Added: trunk/packages/plink/trunk/debian/control
===================================================================
--- trunk/packages/plink/trunk/debian/control	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/control	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,19 @@
+Source: plink
+Section: science
+Priority: optional
+Maintainer: Steffen Moeller <moeller at debian.org>
+Build-Depends: debhelper (>= 5)
+Standards-Version: 3.7.3
+Homepage: http://pngu.mgh.harvard.edu/~purcell/plink/
+
+Package: plink
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: whole-genome association analysis toolset
+ plink expects as input the data from SNP (single 
+ nucleotide polymorphism) chips of many individuals
+ and their phenotypical description of a disease.
+ It finds associations of single or pairs of DNA
+ variations with a phenotype and can retrieve 
+ SNP annotation from an online source.
+

Added: trunk/packages/plink/trunk/debian/copyright
===================================================================
--- trunk/packages/plink/trunk/debian/copyright	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/copyright	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,41 @@
+This package was debianized by Steffen Moeller <moeller at debian.org> on
+Tue, 08 Apr 2008 17:49:32 +0200.
+
+It was downloaded from http://pngu.mgh.harvard.edu/~purcell/plink
+
+Upstream Author: 
+
+    Shaun Purcell <plink at chgr.mgh.harvard.edu>
+
+Copyright: 
+
+    Rconnection.cpp:
+	
+ 	Copyright (C) 2004 Simon Urbanek, All rights reserved.
+
+    All other code (dcdflib.cpp has no copyright information):
+
+    	Copyright (C) 2005-2008  Shaun Purcell <plink at chgr.mgh.harvard.edu>
+
+
+License:
+
+    This package is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+ 
+    This package is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with this package; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+
+On Debian systems, the complete text of the GNU General
+Public License can be found in `/usr/share/common-licenses/GPL'.
+
+The Debian packaging is (C) 2008, Steffen Moeller <moeller at debian.org> and
+is licensed under the GPL, see `/usr/share/common-licenses/GPL'.

Added: trunk/packages/plink/trunk/debian/dirs
===================================================================
--- trunk/packages/plink/trunk/debian/dirs	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/dirs	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1 @@
+usr/bin

Added: trunk/packages/plink/trunk/debian/docs
===================================================================
--- trunk/packages/plink/trunk/debian/docs	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/docs	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1 @@
+README.txt

Added: trunk/packages/plink/trunk/debian/manpage.sgml.ex
===================================================================
--- trunk/packages/plink/trunk/debian/manpage.sgml.ex	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/manpage.sgml.ex	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,156 @@
+<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
+
+<!-- Process this file with docbook-to-man to generate an nroff manual
+     page: `docbook-to-man manpage.sgml > manpage.1'.  You may view
+     the manual page with: `docbook-to-man manpage.sgml | nroff -man |
+     less'.  A typical entry in a Makefile or Makefile.am is:
+
+manpage.1: manpage.sgml
+	docbook-to-man $< > $@
+
+    
+	The docbook-to-man binary is found in the docbook-to-man package.
+	Please remember that if you create the nroff version in one of the
+	debian/rules file targets (such as build), you will need to include
+	docbook-to-man in your Build-Depends control field.
+
+  -->
+
+  <!-- Fill in your name for FIRSTNAME and SURNAME. -->
+  <!ENTITY dhfirstname "<firstname>FIRSTNAME</firstname>">
+  <!ENTITY dhsurname   "<surname>SURNAME</surname>">
+  <!-- Please adjust the date whenever revising the manpage. -->
+  <!ENTITY dhdate      "<date>April  8, 2008</date>">
+  <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
+       allowed: see man(7), man(1). -->
+  <!ENTITY dhsection   "<manvolnum>SECTION</manvolnum>">
+  <!ENTITY dhemail     "<email>moeller at debian.org</email>">
+  <!ENTITY dhusername  "Steffen Moeller">
+  <!ENTITY dhucpackage "<refentrytitle>PLINK</refentrytitle>">
+  <!ENTITY dhpackage   "plink">
+
+  <!ENTITY debian      "<productname>Debian</productname>">
+  <!ENTITY gnu         "<acronym>GNU</acronym>">
+  <!ENTITY gpl         "&gnu; <acronym>GPL</acronym>">
+]>
+
+<refentry>
+  <refentryinfo>
+    <address>
+      &dhemail;
+    </address>
+    <author>
+      &dhfirstname;
+      &dhsurname;
+    </author>
+    <copyright>
+      <year>2003</year>
+      <holder>&dhusername;</holder>
+    </copyright>
+    &dhdate;
+  </refentryinfo>
+  <refmeta>
+    &dhucpackage;
+
+    &dhsection;
+  </refmeta>
+  <refnamediv>
+    <refname>&dhpackage;</refname>
+
+    <refpurpose>program to do something</refpurpose>
+  </refnamediv>
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>&dhpackage;</command>
+
+      <arg><option>-e <replaceable>this</replaceable></option></arg>
+
+      <arg><option>--example <replaceable>that</replaceable></option></arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+  <refsect1>
+    <title>DESCRIPTION</title>
+
+    <para>This manual page documents briefly the
+      <command>&dhpackage;</command> and <command>bar</command>
+      commands.</para>
+
+    <para>This manual page was written for the &debian; distribution
+      because the original program does not have a manual page.
+      Instead, it has documentation in the &gnu;
+      <application>Info</application> format; see below.</para>
+
+    <para><command>&dhpackage;</command> is a program that...</para>
+
+  </refsect1>
+  <refsect1>
+    <title>OPTIONS</title>
+
+    <para>These programs follow the usual &gnu; command line syntax,
+      with long options starting with two dashes (`-').  A summary of
+      options is included below.  For a complete description, see the
+      <application>Info</application> files.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><option>-h</option>
+          <option>--help</option>
+        </term>
+        <listitem>
+          <para>Show summary of options.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>-v</option>
+          <option>--version</option>
+        </term>
+        <listitem>
+          <para>Show version of program.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+  <refsect1>
+    <title>SEE ALSO</title>
+
+    <para>bar (1), baz (1).</para>
+
+    <para>The programs are documented fully by <citetitle>The Rise and
+      Fall of a Fooish Bar</citetitle> available via the
+      <application>Info</application> system.</para>
+  </refsect1>
+  <refsect1>
+    <title>AUTHOR</title>
+
+    <para>This manual page was written by &dhusername; &dhemail; for
+      the &debian; system (but may be used by others).  Permission is
+      granted to copy, distribute and/or modify this document under
+      the terms of the &gnu; General Public License, Version 2 any 
+	  later version published by the Free Software Foundation.
+    </para>
+	<para>
+	  On Debian systems, the complete text of the GNU General Public
+	  License can be found in /usr/share/common-licenses/GPL.
+	</para>
+
+  </refsect1>
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
+
+

Added: trunk/packages/plink/trunk/debian/manpage.xml.ex
===================================================================
--- trunk/packages/plink/trunk/debian/manpage.xml.ex	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/manpage.xml.ex	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,144 @@
+<?xml version='1.0' encoding='ISO-8859-1'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+
+<!--
+
+Process this file with an XSLT processor: `xsltproc \
+-''-nonet /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\
+manpages/docbook.xsl manpage.dbk'.  A manual page
+<package>.<section> will be generated.  You may view the
+manual page with: nroff -man <package>.<section> | less'.  A
+typical entry in a Makefile or Makefile.am is:
+
+DB2MAN=/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\
+manpages/docbook.xsl
+XP=xsltproc -''-nonet
+
+manpage.1: manpage.dbk
+        $(XP) $(DB2MAN) $<
+    
+The xsltproc binary is found in the xsltproc package.  The
+XSL files are in docbook-xsl.  Please remember that if you
+create the nroff version in one of the debian/rules file
+targets (such as build), you will need to include xsltproc
+and docbook-xsl in your Build-Depends control field.
+
+-->
+
+  <!-- Fill in your name for FIRSTNAME and SURNAME. -->
+  <!ENTITY dhfirstname "<firstname>FIRSTNAME</firstname>">
+  <!ENTITY dhsurname   "<surname>SURNAME</surname>">
+  <!-- Please adjust the date whenever revising the manpage. -->
+  <!ENTITY dhdate      "<date>April  8, 2008</date>">
+  <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
+       allowed: see man(7), man(1). -->
+  <!ENTITY dhsection   "<manvolnum>SECTION</manvolnum>">
+  <!ENTITY dhemail     "<email>moeller at debian.org</email>">
+  <!ENTITY dhusername  "Steffen Moeller">
+  <!ENTITY dhucpackage "<refentrytitle>PLINK</refentrytitle>">
+  <!ENTITY dhpackage   "plink">
+
+  <!ENTITY debian      "<productname>Debian</productname>">
+  <!ENTITY gnu         "<acronym>GNU</acronym>">
+  <!ENTITY gpl         "&gnu; <acronym>GPL</acronym>">
+]>
+
+<refentry>
+  <refentryinfo>
+    <address>
+      &dhemail;
+    </address>
+    <copyright>
+      <year>2007</year>
+      <holder>&dhusername;</holder>
+    </copyright>
+    &dhdate;
+  </refentryinfo>
+  <refmeta>
+    &dhucpackage;
+
+    &dhsection;
+  </refmeta>
+  <refnamediv>
+    <refname>&dhpackage;</refname>
+
+    <refpurpose>program to do something</refpurpose>
+  </refnamediv>
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>&dhpackage;</command>
+
+      <arg><option>-e <replaceable>this</replaceable></option></arg>
+
+      <arg><option>--example <replaceable>that</replaceable></option></arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+  <refsect1>
+    <title>DESCRIPTION</title>
+
+    <para>This manual page documents briefly the
+      <command>&dhpackage;</command> and <command>bar</command>
+      commands.</para>
+
+    <para>This manual page was written for the &debian; distribution
+      because the original program does not have a manual page.
+      Instead, it has documentation in the &gnu;
+      <application>Info</application> format; see below.</para>
+
+    <para><command>&dhpackage;</command> is a program that...</para>
+
+  </refsect1>
+  <refsect1>
+    <title>OPTIONS</title>
+
+    <para>These programs follow the usual &gnu; command line syntax,
+      with long options starting with two dashes (`-').  A summary of
+      options is included below.  For a complete description, see the
+      <application>Info</application> files.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><option>-h</option>
+          <option>--help</option>
+        </term>
+        <listitem>
+          <para>Show summary of options.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>-v</option>
+          <option>--version</option>
+        </term>
+        <listitem>
+          <para>Show version of program.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+  <refsect1>
+    <title>SEE ALSO</title>
+
+    <para>bar (1), baz (1).</para>
+
+    <para>The programs are documented fully by <citetitle>The Rise and
+      Fall of a Fooish Bar</citetitle> available via the
+      <application>Info</application> system.</para>
+  </refsect1>
+  <refsect1>
+    <title>AUTHOR</title>
+
+    <para>This manual page was written by &dhusername; &dhemail; for
+      the &debian; system (but may be used by others).  Permission is
+      granted to copy, distribute and/or modify this document under
+      the terms of the &gnu; General Public License, Version 2 any 
+	  later version published by the Free Software Foundation.
+    </para>
+	<para>
+	  On Debian systems, the complete text of the GNU General Public
+	  License can be found in /usr/share/common-licenses/GPL.
+	</para>
+
+  </refsect1>
+</refentry>
+

Added: trunk/packages/plink/trunk/debian/menu.ex
===================================================================
--- trunk/packages/plink/trunk/debian/menu.ex	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/menu.ex	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,2 @@
+?package(plink):needs="X11|text|vc|wm" section="Applications/see-menu-manual"\
+  title="plink" command="/usr/bin/plink"

Added: trunk/packages/plink/trunk/debian/patches/gcc43.patch
===================================================================
--- trunk/packages/plink/trunk/debian/patches/gcc43.patch	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/patches/gcc43.patch	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,136 @@
+Index: plink-1.02/Makefile
+===================================================================
+--- plink-1.02.orig/Makefile	2008-04-08 18:34:04.000000000 +0200
++++ plink-1.02/Makefile	2008-04-08 22:40:59.000000000 +0200
+@@ -17,12 +17,12 @@
+ SYS = UNIX
+ 
+ # Leave blank after "=" to disable; put "= 1" to enable
+-WITH_R_PLUGINS = 1
++WITH_R_PLUGINS = 
+ WITH_WEBCHECK = 1
+ FORCE_32BIT = 
+ 
+ # Put C++ compiler here; Windows has it's own specific version
+-CXX_UNIX = g++
++CXX_UNIX = g++-3.3
+ CXX_WIN = c:\bin\mingw\bin\mingw32-g++.exe
+ 
+ # Any other compiler flags here ( -Wall, -g, etc)
+@@ -43,7 +43,7 @@
+ endif
+ 
+ ifeq ($(SYS),UNIX)
+- CXXFLAGS += -DUNIX -static
++ CXXFLAGS += -DUNIX
+  CXX = $(CXX_UNIX)
+ endif
+ 
+@@ -115,3 +115,6 @@
+ 
+ clean:
+ 	rm -f *.o *~
++
++distclean: clean
++	rm -f plink
+Index: plink-1.02/clumpld.cpp
+===================================================================
+--- plink-1.02.orig/clumpld.cpp	2008-04-08 18:22:12.000000000 +0200
++++ plink-1.02/clumpld.cpp	2008-04-08 18:22:17.000000000 +0200
+@@ -11,6 +11,7 @@
+ //////////////////////////////////////////////////////////////////
+ 
+ 
++#include <algorithm>
+ #include <iostream>
+ #include <iomanip>
+ #include <fstream>
+Index: plink-1.02/filters.cpp
+===================================================================
+--- plink-1.02.orig/filters.cpp	2008-04-08 17:53:21.000000000 +0200
++++ plink-1.02/filters.cpp	2008-04-08 17:53:35.000000000 +0200
+@@ -18,6 +18,7 @@
+ #include <vector>
+ #include <map>
+ #include <cmath>
++#include <cstdlib>
+ #include <iterator>
+ #include "plink.h"
+ #include "options.h"
+Index: plink-1.02/fisher.cpp
+===================================================================
+--- plink-1.02.orig/fisher.cpp	2008-04-08 18:05:24.000000000 +0200
++++ plink-1.02/fisher.cpp	2008-04-08 18:12:06.000000000 +0200
+@@ -11,6 +11,8 @@
+ //////////////////////////////////////////////////////////////////
+ 
+ 
++#include <climits>
++#include <string>
+ #include "fisher.h"
+ #include "plink.h"
+ #include "helper.h"
+Index: plink-1.02/nlist.cpp
+===================================================================
+--- plink-1.02.orig/nlist.cpp	2008-04-08 18:15:22.000000000 +0200
++++ plink-1.02/nlist.cpp	2008-04-08 18:22:45.000000000 +0200
+@@ -10,7 +10,9 @@
+ //                                                              //
+ //////////////////////////////////////////////////////////////////
+ 
++#include <algorithm>
+ #include <string>
++#include <cstdio>
+ #include <vector>
+ 
+ #include "nlist.h"
+Index: plink-1.02/parse.cpp
+===================================================================
+--- plink-1.02.orig/parse.cpp	2008-04-08 18:14:57.000000000 +0200
++++ plink-1.02/parse.cpp	2008-04-08 18:15:07.000000000 +0200
+@@ -14,6 +14,7 @@
+ #include <iostream>
+ #include <string>
+ #include <cmath>
++#include <cstdlib>
+ #include "options.h"
+ #include "helper.h"
+ 
+Index: plink-1.02/perm.cpp
+===================================================================
+--- plink-1.02.orig/perm.cpp	2008-04-08 17:58:45.000000000 +0200
++++ plink-1.02/perm.cpp	2008-04-08 18:21:20.000000000 +0200
+@@ -15,6 +15,9 @@
+ #include "helper.h"
+ #include <iostream>
+ #include <cmath>
++#include <cstdlib>
++#include <algorithm>
++#include <vector>
+ 
+ Perm::Perm(Plink & pref) : P(pref)
+ {
+Index: plink-1.02/prephap.cpp
+===================================================================
+--- plink-1.02.orig/prephap.cpp	2008-04-08 17:54:54.000000000 +0200
++++ plink-1.02/prephap.cpp	2008-04-08 17:55:02.000000000 +0200
+@@ -18,6 +18,7 @@
+ #include <cmath>
+ #include <vector>
+ #include <map>
++#include <cstdlib>
+ 
+ #include "plink.h"
+ #include "options.h"
+Index: plink-1.02/proxy.cpp
+===================================================================
+--- plink-1.02.orig/proxy.cpp	2008-04-08 18:21:37.000000000 +0200
++++ plink-1.02/proxy.cpp	2008-04-08 18:21:46.000000000 +0200
+@@ -11,6 +11,7 @@
+ //////////////////////////////////////////////////////////////////
+ 
+ 
++#include <algorithm>
+ #include <iostream>
+ #include <iomanip>
+ #include <string>

Added: trunk/packages/plink/trunk/debian/patches/series
===================================================================
--- trunk/packages/plink/trunk/debian/patches/series	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/patches/series	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1 @@
+gcc43.patch

Added: trunk/packages/plink/trunk/debian/plink-default.ex
===================================================================
--- trunk/packages/plink/trunk/debian/plink-default.ex	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/plink-default.ex	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,10 @@
+# Defaults for plink initscript
+# sourced by /etc/init.d/plink
+# installed at /etc/default/plink by the maintainer scripts
+
+#
+# This is a POSIX shell fragment
+#
+
+# Additional options that are passed to the Daemon.
+DAEMON_OPTS=""

Added: trunk/packages/plink/trunk/debian/plink.1
===================================================================
--- trunk/packages/plink/trunk/debian/plink.1	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/plink.1	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,25 @@
+.\"                                      Hey, EMACS: -*- nroff -*-
+.TH PLINK 1 "April  8, 2008"
+.SH NAME
+plink \- whole genome SNP analysis
+.SH SYNOPSIS
+.B plink --help
+.SH DESCRIPTION
+
+plink works on SNP datasets that have already been pre-analysed for
+their reliability and their calling to AA, BB or AB. It finds associations
+with a disease of single SNPs or pairs, determines haplotype blocks or
+retrieves information on SNPs from an online repository.
+
+This manual page must be insufficient. Please use the help option for a
+quick reminder of the options of plink or turn to its home page with
+the online documentation or the downloadable manual. 
+
+.SH SEE ALSO
+.BR http://pngu.mgh.harvard.edu/~purcell/plink
+
+.SH AUTHOR
+plink was written by Shaun Purcell <plink at chgr.mgh.harvard.edu>
+.PP
+This manual page was written by Steffen Moeller <moeller at debian.org>,
+for the Debian project (but may be used by others).

Added: trunk/packages/plink/trunk/debian/plink.doc-base.EX
===================================================================
--- trunk/packages/plink/trunk/debian/plink.doc-base.EX	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/plink.doc-base.EX	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,22 @@
+Document: plink
+Title: Debian plink Manual
+Author: <insert document author here>
+Abstract: This manual describes what plink is
+ and how it can be used to
+ manage online manuals on Debian systems.
+Section: unknown
+
+Format: debiandoc-sgml
+Files: /usr/share/doc/plink/plink.sgml.gz
+
+Format: postscript
+Files: /usr/share/doc/plink/plink.ps.gz
+
+Format: text
+Files: /usr/share/doc/plink/plink.text.gz
+
+Format: HTML
+Index: /usr/share/doc/plink/html/index.html
+Files: /usr/share/doc/plink/html/*.html
+
+  

Added: trunk/packages/plink/trunk/debian/plink.install
===================================================================
--- trunk/packages/plink/trunk/debian/plink.install	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/plink.install	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1 @@
+plink usr/bin

Added: trunk/packages/plink/trunk/debian/rules
===================================================================
--- trunk/packages/plink/trunk/debian/rules	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/rules	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,51 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+
+build: build-stamp
+
+build-stamp:
+	dh_testdir
+	$(MAKE)
+	#docbook-to-man debian/plink.sgml > plink.1
+	touch $@
+
+clean:
+	dh_testdir
+	dh_testroot
+	rm -f build-stamp configure-stamp
+	$(MAKE) distclean
+	dh_clean 
+
+install: build
+	dh_testdir
+	dh_testroot
+	dh_clean -k 
+	dh_installdirs
+	#cp plink $(CURDIR)/debian/plink/usr/bin/
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+	dh_testdir
+	dh_testroot
+	dh_installchangelogs 
+	dh_installdocs
+	dh_installexamples test.ped test.map
+	dh_install
+	dh_installman debian/plink.1
+	dh_link
+	dh_strip
+	dh_compress
+	dh_fixperms
+	dh_installdeb
+	dh_shlibdeps
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure


Property changes on: trunk/packages/plink/trunk/debian/rules
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/packages/plink/trunk/debian/watch
===================================================================
--- trunk/packages/plink/trunk/debian/watch	                        (rev 0)
+++ trunk/packages/plink/trunk/debian/watch	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,2 @@
+version=3
+http://pngu.mgh.harvard.edu/~purcell/plink/dist/plink-(.*)-src.zip

Modified: trunk/packages/plink/trunk/filters.cpp
===================================================================
--- trunk/packages/plink/trunk/filters.cpp	2008-04-09 09:42:57 UTC (rev 1724)
+++ trunk/packages/plink/trunk/filters.cpp	2008-04-09 09:43:11 UTC (rev 1725)
@@ -18,6 +18,7 @@
 #include <vector>
 #include <map>
 #include <cmath>
+#include <cstdlib>
 #include <iterator>
 #include "plink.h"
 #include "options.h"

Modified: trunk/packages/plink/trunk/fisher.cpp
===================================================================
--- trunk/packages/plink/trunk/fisher.cpp	2008-04-09 09:42:57 UTC (rev 1724)
+++ trunk/packages/plink/trunk/fisher.cpp	2008-04-09 09:43:11 UTC (rev 1725)
@@ -11,6 +11,8 @@
 //////////////////////////////////////////////////////////////////
 
 
+#include <climits>
+#include <string>
 #include "fisher.h"
 #include "plink.h"
 #include "helper.h"

Modified: trunk/packages/plink/trunk/nlist.cpp
===================================================================
--- trunk/packages/plink/trunk/nlist.cpp	2008-04-09 09:42:57 UTC (rev 1724)
+++ trunk/packages/plink/trunk/nlist.cpp	2008-04-09 09:43:11 UTC (rev 1725)
@@ -10,7 +10,9 @@
 //                                                              //
 //////////////////////////////////////////////////////////////////
 
+#include <algorithm>
 #include <string>
+#include <cstdio>
 #include <vector>
 
 #include "nlist.h"

Modified: trunk/packages/plink/trunk/parse.cpp
===================================================================
--- trunk/packages/plink/trunk/parse.cpp	2008-04-09 09:42:57 UTC (rev 1724)
+++ trunk/packages/plink/trunk/parse.cpp	2008-04-09 09:43:11 UTC (rev 1725)
@@ -14,6 +14,7 @@
 #include <iostream>
 #include <string>
 #include <cmath>
+#include <cstdlib>
 #include "options.h"
 #include "helper.h"
 

Modified: trunk/packages/plink/trunk/perm.cpp
===================================================================
--- trunk/packages/plink/trunk/perm.cpp	2008-04-09 09:42:57 UTC (rev 1724)
+++ trunk/packages/plink/trunk/perm.cpp	2008-04-09 09:43:11 UTC (rev 1725)
@@ -15,6 +15,9 @@
 #include "helper.h"
 #include <iostream>
 #include <cmath>
+#include <cstdlib>
+#include <algorithm>
+#include <vector>
 
 Perm::Perm(Plink & pref) : P(pref)
 {

Added: trunk/packages/plink/trunk/plink.log
===================================================================
--- trunk/packages/plink/trunk/plink.log	                        (rev 0)
+++ trunk/packages/plink/trunk/plink.log	2008-04-09 09:43:11 UTC (rev 1725)
@@ -0,0 +1,13 @@
+
+ at ----------------------------------------------------------@
+|        PLINK!       |     v1.02      |   27/Mar/2008     |
+|----------------------------------------------------------|
+|  (C) 2008 Shaun Purcell, GNU General Public License, v2  |
+|----------------------------------------------------------|
+|  For documentation, citation & bug-report instructions:  |
+|        http://pngu.mgh.harvard.edu/purcell/plink/        |
+ at ----------------------------------------------------------@
+
+
+Analysis finished: Wed Apr  9 00:35:19 2008
+

Modified: trunk/packages/plink/trunk/prephap.cpp
===================================================================
--- trunk/packages/plink/trunk/prephap.cpp	2008-04-09 09:42:57 UTC (rev 1724)
+++ trunk/packages/plink/trunk/prephap.cpp	2008-04-09 09:43:11 UTC (rev 1725)
@@ -18,6 +18,7 @@
 #include <cmath>
 #include <vector>
 #include <map>
+#include <cstdlib>
 
 #include "plink.h"
 #include "options.h"

Modified: trunk/packages/plink/trunk/proxy.cpp
===================================================================
--- trunk/packages/plink/trunk/proxy.cpp	2008-04-09 09:42:57 UTC (rev 1724)
+++ trunk/packages/plink/trunk/proxy.cpp	2008-04-09 09:43:11 UTC (rev 1725)
@@ -11,6 +11,7 @@
 //////////////////////////////////////////////////////////////////
 
 
+#include <algorithm>
 #include <iostream>
 #include <iomanip>
 #include <string>




More information about the debian-med-commit mailing list