Index: /branches/eam_branches/ipp-20140904/Ohana/src/fakeastro/src/fakeastro.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/fakeastro/src/fakeastro.c	(revision 37495)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/fakeastro/src/fakeastro.c	(revision 37496)
@@ -18,4 +18,8 @@
       exit (0);
 
+    case OP_2MASS:
+      fakeastro_2mass ();
+      exit (0);
+
     default:
       fprintf (stderr, "impossible!\n");
Index: /branches/eam_branches/ipp-20140904/Ohana/src/fakeastro/src/fakeastro_2mass.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/fakeastro/src/fakeastro_2mass.c	(revision 37496)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/fakeastro/src/fakeastro_2mass.c	(revision 37496)
@@ -0,0 +1,51 @@
+# include "fakeastro.h"
+
+int fakeastro_2mass () {
+
+  INITTIME;
+
+  SkyTable *skyTable = SkyTableLoadOptimal (CATDIR, SKY_TABLE, GSCFILE, TRUE, SKY_DEPTH, VERBOSE);
+  SkyTableSetFilenames (skyTable, CATDIR, "cpt");
+
+  SkyList *skyList  = SkyListByPatch (skyTable, -1, &UserPatch);
+
+  Catalog catalog;
+
+  // load stars from database in these regions
+  int i;
+  for (i = 0; i < skylist->Nregions; i++) {
+    dvo_catalog_init (&catalog, TRUE);
+
+    // set the parameters which guide catalog open/load/create
+    catalog.filename  = skylist[0].filename[i];
+    catalog.catformat = dvo_catalog_catformat (CATFORMAT);  // set the default catformat from config data
+    catalog.catmode   = dvo_catalog_catmode (CATMODE);      // set the default catmode from config data
+    catalog.catflags  = LOAD_AVES | LOAD_SECF | LOAD_MEAS  | LOAD_STARPAR;
+    catalog.Nsecfilt  = GetPhotcodeNsecfilt ();
+    if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE, "r")) {
+      fprintf (stderr, "ERROR: failure reading catalog %s\n", catalog.filename);
+      exit (1);
+    }
+    if (!catalog.Naves_disk) {
+	if (VERBOSE2) { fprintf (stderr, "no data in %s, skipping\n", catalog.filename); }
+	dvo_catalog_unlock (&catalog);
+	dvo_catalog_free (&catalog);
+	continue;
+    }
+
+    make_2mass_measures (&catalog);
+
+    SetProtect (TRUE);
+    dvo_catalog_update (&catalog, VERBOSE);
+    SetProtect (FALSE);
+
+    dvo_catalog_unlock (&catalog);
+    dvo_catalog_free (&catalog);
+    if (VERBOSE) MARKTIME ("save cpt: %f sec\n", dtime); RESETTIME; 
+    
+
+
+  exit (0);
+}
+
+
Index: /branches/eam_branches/ipp-20140904/Ohana/src/fakeastro/src/make_2mass_measures.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/fakeastro/src/make_2mass_measures.c	(revision 37496)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/fakeastro/src/make_2mass_measures.c	(revision 37496)
@@ -0,0 +1,72 @@
+# include "fakeastro.h"
+
+// region corresponds to the catalog
+int make_2mass_measures (Catalog *catalog) {
+
+  Average *average = catalog->average;
+  SecFilt *secfilt = catalog->secfilt;
+  StarPar *starpar = catalog->starpar;
+  Measure *measure = catalog->measure;
+  
+  int i;
+  for (i = 0; i < catalog->Naverage; i++) {
+
+    int nStar = average[i].starparOffset;
+
+    // which filter?
+    double y_PS1 = secfilt[i*Nsecfilt + 4].M  - ZP;
+    double Counts = pow(10.0, -0.4*Minst);
+
+    double SN = Counts / sqrt(SkyCts + Counts);
+
+    // true position from src catalog
+    // XXX need to save the true position somewhere...
+    double Rtru = average[i].R;
+    double Dtru = average[i].D;
+
+    // observed position is scattered from true position by:
+    // * proper motion
+    // * gaussian scatter (~ seeing) 
+    double uR = starpar[nStar].uRA; // starpar are in arcsec / year
+    double uD = starpar[nStar].uDEC;
+    
+    // tzero, timeRef are in UNIX seconds, Toffset should be in years
+    double Toffset = (tzero_2mass - timeRef) / 365.25 / 86400.0;
+
+    // uR,uD in linear (arcsec / yr)
+    double dRpm = uR*Toffset;
+    double dDpm = uD*Toffset;
+
+    // uR,uD in linear arcsec
+    double dRsee = rnd_gauss (0.0, 1.0 / SN);
+    double dDsee = rnd_gauss (0.0, 1.0 / SN);
+
+    double dRoff = (dRpm + dRsee) / 3600.0;
+    double dDoff = (dDpm + dDsee) / 3600.0;
+
+    double Robs = Rtru + dRoff / cos(Dtru*RAD_DEG);
+    double Dobs = Dtru + dDoff;
+
+    measure[nMeasure].M      = Minst + ZP;
+    measure[nMeasure].dM     = 1.0 / SN;
+
+    // stars[Nstars].measure.dMcal      = ps1data[i].dMcal;
+    measure[nMeasure].Sky        = sky[Nsec];
+    measure[nMeasure].dSky       = sqrt(sky[Nsec]);
+    measure[nMeasure].photFlags  = 0;
+    measure[nMeasure].photFlags2 = 0;
+    measure[nMeasure].R = Robs;
+    measure[nMeasure].D = Dobs;
+    measure[nMeasure].airmass = airmass (image->secz, stars[Nstars].average.R, stars[Nstars].average.D, image->sidtime, image->latitude);
+    measure[nMeasure].az      = azimuth (15.0*image->sidtime - stars[Nstars].average.R, stars[Nstars].average.D, image->latitude);
+    measure[nMeasure].Mcal    = image->Mcal;
+    measure[nMeasure].t       = image->tzero + 1e-4*stars[Nstars].measure.Yccd*image->trate;  // trate is in 0.1 msec / row 
+    measure[nMeasure].dt      = Mtime;
+
+    measure[nMeasure].imageID = 0;
+
+    // This is may optionally be replaced by the internal sequence (see FilterStars.c)
+    measure[nMeasure].detID      = Nstars + 1;
+    Nstars ++;
+  }
+}
