Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

make_ccd.C

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 //
00033 //
00034 //   version 1.0:  September 1999   Simon F. Portegies Zwart
00035 //                                  spz@komodo.bu.edu
00036 //
00037 //++ version 1.0: basic ccd creation routines.
00038 //++         2.0: output file written in FITS format
00039 //++         3.0: added: overexposure bleading
00040 //++                     dask current
00041 //++                     read out noise
00042 //++                     scyntilation
00043 //++                     thermal luminosity
00044 //
00045 
00046 #include "single_star.h"
00047 #include "sstar_to_dyn.h"
00048 #include "dyn.h"
00049 
00050 #include <fitsio.h>
00051 
00052 enum wavelength {U=0, B, F, R, J};
00053 
00054 #define XCCD_MAX 512
00055 #define YCCD_MAX 512
00056 
00057 //#define ARCSEC_PER_PIXEL 0.0455  // HST WFPC
00058 //#define ARCSEC_PER_PIXEL 0.0966  // HST Planetary camera
00059 //#define ARCSEC_PER_PIXEL 0.076
00060 //#define ARCSEC_PER_PIXEL 0.49    // 0.9m Cassegrain telescope
00061 //#define ARCSEC_PER_PIXEL 0.15
00062 //#define ARCSEC_PER_PIXEL 0.30      // [arcsec] Ken Janes
00063 //#define FWHM             0.70      // [arcsec]
00064 
00065 #define SATURATION_LIMIT 65536
00066 
00067 #ifdef TOOLBOX
00068 
00069 local real hst_psf(real r) {
00070 
00071     real a, b, c, d, e;
00072         
00073     a = 6.66183E-01;
00074     b = 3.51739E-01;
00075     c = -1.17196E-01;
00076     d = 1.50760E-02;
00077     e = -6.55790E-04;
00078 
00079     real f=1;
00080     if(r<=9)
00081     f = a + r*(b + r*(c + r*(d + r*e))) - 0.3; 
00082 
00083     return f;
00084 } 
00085 
00086 local real Kolmogorov_psf(real r, real beta, real fwhm) {
00087 
00088     real hw = 0.5 * fwhm;
00089 
00090     real first_part = 1./(cnsts.mathematics(pi)*pow(hw, 2));
00091     real teller = (pow(2, 1./beta)-1) * (beta - 1);
00092     real noemer = pow(1 + (pow(2, 1./beta)-1)*pow(r/hw, 2), beta);
00093 
00094     real I = first_part * teller/noemer;
00095 
00096     return I;
00097 }
00098 
00099 local void print_ccd(real **ccd, char filename[], real t_exposure) { 
00100 
00101     fitsfile *fptr;
00102     int status, ii, jj;
00103     long  fpixel, nelements, exposure;
00104     unsigned short array[512][512];  
00105 
00106 //    char filename[] = "ccd.fit";
00107     int bitpix   =  USHORT_IMG; 
00108     long naxis    =   2;
00109     long naxes[2] = { 512, 512 }; 
00110 
00111     remove(filename); 
00112     status = 0;
00113 
00114 
00115     if (fits_create_file(&fptr, filename, &status)) 
00116          printf("%s\n", status);       
00117 
00118     if ( fits_create_img(fptr,  bitpix, naxis, naxes, &status) )
00119          printf("%s\n", status);     
00120 
00121     float val;
00122     for (jj = 0; jj < naxes[1]; jj++) {   
00123       for (ii = 0; ii < naxes[0]; ii++) {
00124 //          cin >> val;
00125             array[jj][ii] = (unsigned short)ccd[jj][ii];
00126         }
00127     }
00128 
00129     fpixel = 1;
00130     nelements = naxes[0] * naxes[1]; 
00131 
00132     if ( fits_write_img(fptr, TUSHORT, fpixel, nelements, array[0], &status) )
00133          printf("%s\n", status);
00134 
00135     exposure = long(t_exposure);
00136     if ( fits_update_key(fptr, TLONG, "EXPOSURE", &exposure,
00137          "Exposure time in seconds", &status) )
00138          printf("%s\n", status);  
00139 
00140     if ( fits_close_file(fptr, &status) )  
00141          printf("%s\n", status);        
00142 }
00143 
00144 real **mkarray(int rows, int cols) {
00145     real ** ret = new real *[rows];
00146     for (int i=0; i<cols; i++)
00147         ret[i] = new real[cols];
00148 
00149     for (int i=0; i<rows; i++)
00150         for (int j=0; j<cols; j++) {
00151         ret[i][j] = 0;
00152     }
00153 
00154     cerr << "Datafile read"<<endl;
00155     return ret;
00156 }
00157 
00158 local bool add_star_to_ccd(real** ccd, real luminosity, 
00159                            real xpos, real ypos, real beta_PSF,
00160                            real arcsec_per_pixel, real fwhm) {
00161 
00162   int nx = (int)floor(xpos/arcsec_per_pixel);
00163   int ny = (int)floor(ypos/arcsec_per_pixel);
00164   
00165 //  PRC(nx);PRC(ny);PRC(luminosity);
00166   if (nx<-10 || nx>XCCD_MAX+10 || ny<-10 || ny>YCCD_MAX+10) {
00167 
00168     //cerr << ": not added"<<endl;
00169     return false;
00170   }
00171 
00172 //  if(luminosity>0) {
00173     real magn = 4.76 - 2.5*log10(luminosity);
00174 //    PRC(nx);PRC(ny);PRL(magn);
00175 //  }
00176 
00177   real r_locus;
00178   real norm = Kolmogorov_psf(0, beta_PSF, fwhm);
00179   int n_psf = int(10*fwhm/arcsec_per_pixel);
00180   
00181   for(int ix = max(0, nx-n_psf); ix<min(XCCD_MAX, nx+n_psf); ix++) 
00182     for(int iy = max(0, ny-n_psf); iy<min(YCCD_MAX, ny+n_psf); iy++) {
00183 
00184       r_locus = sqrt(pow(xpos-ix*arcsec_per_pixel, 2) 
00185                      +      pow(ypos-iy*arcsec_per_pixel, 2)); 
00186       
00187       ccd[ix][iy] += luminosity 
00188                    * Kolmogorov_psf(r_locus, beta_PSF, fwhm)/norm;
00189     }
00190 
00191     return true;
00192 }
00193 
00194 // The exposure time is calubrated to the upper luminosity limit and the
00195 // cluster distance.
00196 // We assume that a 1Lsun star at 10pc just gets over exposed in 1. second.
00197 local real calibrate_exposure_time(real upper_Llimit,
00198                                    real distance_modulus) {
00199 
00200   real Mbol = 4.76;
00201   real magn = Mbol - 2.5*log10(upper_Llimit);
00202   real luminosity = pow(10, 0.4*(Mbol-magn));
00203 
00204   real t_exposure = 2./luminosity;
00205 
00206   return t_exposure;              // seconds
00207 
00208 }
00209 
00210 local real add_standard_stars(real **ccd, wavelength band, real beta_PSF,
00211                               real arcsec_per_pixel, real fwhm, bool verbose) {
00212 
00213   real Lu, Lb, Lv, Lr, Li;
00214   Lu= Lb= Lv= Lr= Li = VERY_LARGE_NUMBER;
00215   real logl = 0;    // 1 Lsun
00216   real logt = log10(cnsts.parameters(solar_temperature));
00217   real mass = 1;    // Msun
00218 
00219   ltm_to_ubvri(logl, logt, mass, Lu, Lb, Lv, Lr, Li);
00220 
00221   real luminosity = 0;
00222   switch(band) {
00223     case U: luminosity = pow(10, (4.76-Lu)/2.5);
00224             break;
00225     case B: luminosity = pow(10, (4.76-Lb)/2.5);
00226             break;
00227     case F: luminosity = pow(10, (4.76-Lv)/2.5);
00228             break;
00229     case R: luminosity = pow(10, (4.76-Lr)/2.5);
00230             break;
00231     case J: luminosity = pow(10, (4.76-Li)/2.5);
00232             break;
00233     default:  cerr << "No Default value for magnitude"<<endl;
00234   }
00235 
00236   real xpos = 3*arcsec_per_pixel;
00237   real ypos = 3*arcsec_per_pixel;
00238 
00239   if (verbose) 
00240     cerr << "Add starndard star at pos (x, y): " 
00241          << xpos << " " << ypos << endl;
00242 
00243   add_star_to_ccd(ccd, luminosity, xpos, ypos, beta_PSF, 
00244                   arcsec_per_pixel, fwhm);
00245 
00246 }
00247 
00248 local real get_luminosity(dyn* bi, wavelength band,
00249                           real distance_modulus,
00250                           real luminosity_norm) {
00251 
00252   real Lu, Lb, Lv, Lr, Li;
00253   Lu= Lb= Lv= Lr= Li = VERY_LARGE_NUMBER;
00254   stellar_type stype = NAS;
00255   get_ubvri_star(bi, stype, Lu, Lb, Lv, Lr, Li);
00256 
00257   //    Lu= Lb= Lv= Lr= Li = VERY_LARGE_NUMBER;
00258   //    get_Lubvri_star(bi, stype, Lu, Lb, Lv, Lr, Li);
00259   //    PRC(Lu);PRC(Lb);PRC(Lv);PRC(Lr);PRL(Li);
00260 
00261   real magn;
00262   real Msun;
00263   real air_mass = 0;
00264   switch(band) {
00265     case U: magn = Lu;
00266             Msun = 5.61;
00267             break;
00268     case B: magn = Lb + 0.11*(Lb-Lv) - 0.05 + 0 * air_mass;
00269             Msun = 5.48;
00270             break;
00271     case F: magn = Lv + 0.05*(Lb-Lv) - 0.02 + 0 * air_mass; 
00272             Msun = 4.83;
00273             break;
00274     case R: magn = Lr;
00275             break;
00276     case J: magn = Li;
00277             break;
00278     default:  cerr << "No Default value for magnitude"<<endl;
00279   }
00280 
00281   real Mbol = 4.76;
00282   real luminosity = pow(10, 0.4*(Mbol-magn - distance_modulus));
00283 //  cerr << "Magnitude = " << magn << " ";PRL(luminosity);
00284 
00285   real dL = gauss()*sqrt(luminosity*luminosity_norm);
00286   luminosity += dL/luminosity_norm;
00287 //  PRC(luminosity);PRL(dL);
00288   return luminosity;
00289 }
00290 
00291 local int add_background_stars_to_ccd(real** ccd, wavelength band,
00292                                       real beta_PSF,
00293                                       real arcsec_per_pixel, real fwhm,
00294                                       bool verbose) {
00295 
00296   real luminosity = 0;
00297   real xpos, ypos;
00298   real ccd_size = XCCD_MAX*YCCD_MAX * pow(arcsec_per_pixel/3600., 2);
00299   PRL(ccd_size);
00300 
00301   real a = -5.86697E+00;
00302   real b = 9.95179E-01;
00303   real c = -3.74649E-02;
00304   real d = 6.47974E-04;
00305   real e = -4.38781E-06;
00306 
00307   int n_added=0;
00308   int ns_mag;
00309   real Mv;
00310   for(int imag=4; imag<31; imag++) {
00311     Mv = imag;
00312     ns_mag = (int)(ccd_size * 2.5
00313            * pow(10., a + b*Mv + c*pow(Mv, 2) + d*pow(Mv, 3) + e*pow(Mv, 4)));
00314 
00315     PRC(Mv);PRC(ns_mag);
00316     
00317     for(int i=0; i<ns_mag; i++) {
00318       Mv = randinter((real)imag, (real)imag+1);
00319       if(band!=2) {
00320         Mv += randinter(-0.2, 1.5);
00321       }
00322       luminosity = pow(10, (4.76-Mv)/2.5);
00323       xpos = randinter(0., XCCD_MAX*arcsec_per_pixel);
00324       ypos = randinter(0., YCCD_MAX*arcsec_per_pixel);
00325       if (verbose) {
00326         cerr << "Background star # " << n_added+1
00327              << " pos (x, y): " 
00328              << xpos << " " << ypos << " pixels"; 
00329         cerr << "         magnitudes (M): " << Mv << endl;
00330       }
00331 
00332       if(add_star_to_ccd(ccd, luminosity, xpos, ypos, beta_PSF, 
00333                          arcsec_per_pixel, fwhm)) 
00334         n_added++;
00335     }
00336   }
00337   return n_added;
00338 } 
00339 
00340 local void add_bad_column(real **ccd, int n_bc, bool verbose) {
00341 
00342   // reset input seed.
00343   int input_seed = 11111111;
00344   int actual_seed = srandinter(input_seed);
00345   if (verbose) {
00346     cerr << "Add " << n_bc << " bad columns: ";
00347     PRC(input_seed);PRL(actual_seed);
00348   }
00349 
00350   for(int iy = 0; iy<n_bc; iy++) {
00351 
00352     int iyy = int(randinter(0., YCCD_MAX));
00353     if (verbose)
00354       cerr << "Bad column at: " << iyy << endl;
00355 
00356     for(int ix = 0; ix<XCCD_MAX; ix++) 
00357       ccd[ix][iyy] = 0;
00358   }
00359 
00360 }
00361 
00362 local int add_cosmic_rays(real **ccd, real t_exposure, bool verbose) {
00363 
00364   if (verbose) 
00365     cerr << "Cosmic rays: " << endl;
00366 
00367   int n_cosmics = (int)abs(0.05*t_exposure * gauss());
00368 
00369   int x, y, cosm, n_cosm=0;
00370   int nx, ny;
00371   for (int i=0; i<n_cosmics; i++) {
00372       cosm = (int)abs(SATURATION_LIMIT*gauss());
00373       nx = int(randinter(0, 4));
00374       ny = int(randinter(0, 4));
00375       x = int(randinter(nx, XCCD_MAX-nx));
00376       y = int(randinter(ny, YCCD_MAX-ny));
00377       
00378       if (verbose) {
00379         cerr << "    Cosmic " << cosm << " from (x, y): " << x << " " << y 
00380              << " to: " << x+nx << " " << y+ny << endl; 
00381       }
00382 
00383       for(int ix = x-nx; ix<x+nx; ix++) 
00384         for(int iy = y-ny; iy<y+ny; iy++) {
00385           ccd[ix][iy] = cosm;
00386           n_cosm++;
00387         }
00388     }
00389 
00390   return n_cosm;  
00391 }
00392 
00393 local void saturate_pixel(real **ccd, int ix, int iy, int inc, 
00394                           real maximum_electrons) { 
00395 
00396   if(ccd[ix][iy]>maximum_electrons && ix<XCCD_MAX-1 && ix>0) {
00397 
00398     real excess = ccd[ix][iy]-maximum_electrons;
00399     ccd[ix][iy] -= excess;
00400     ccd[ix+inc][iy] += excess;
00401     saturate_pixel(ccd, ix+inc, iy, inc, maximum_electrons);
00402   }
00403   else 
00404     return;
00405 
00406 }
00407 
00408 local void create_overexposure_marks(real **ccd, real maximum_electrons) { 
00409 
00410   real excess = 0;
00411   for(int ix = 0; ix<XCCD_MAX; ix++) 
00412     for(int iy = 0; iy<YCCD_MAX; iy++)  {
00413 //      excess = ccd[ix][iy]-maximum_electrons;
00414 //      ccd[ix][iy] -= 0.9999*excess;
00415 //      saturate_pixel(ccd, ix, iy, 1, maximum_electrons);
00416 //      ccd[ix][iy] += 0.9999*excess;
00417       saturate_pixel(ccd, ix, iy, -1, maximum_electrons);
00418     }
00419 }
00420 
00421 local void mk_ccd(dyn* b, vector dc_pos, int project, wavelength band,
00422                   real distance, real reddening,
00423                   real upper_Llimit,
00424                   real xoffset, real yoffset,
00425                   real electrons_to_ADU, real beta_PSF,
00426                   real arcsec_per_pixel, real fwhm,
00427                   char* filename, bool add_background_stars,
00428                   bool add_standard_star, int input_seed,
00429                   bool add_cosmics, int nbad_column,
00430                   bool verbose) {
00431 
00432   PRL(band);
00433 
00434   real maximum_electrons = electrons_to_ADU*SATURATION_LIMIT-1;
00435 
00436   real half_xccd = 0.5*XCCD_MAX*arcsec_per_pixel;
00437   real half_yccd = 0.5*YCCD_MAX*arcsec_per_pixel;
00438 
00439   real **ccd = mkarray(XCCD_MAX, YCCD_MAX);
00440   cerr << "CCD allocated"<<endl;
00441   for(int ix = 0; ix<XCCD_MAX; ix++) 
00442     for(int iy = 0; iy<YCCD_MAX; iy++)  
00443       ccd[ix][iy] = 0;
00444 
00445   PRL(distance);
00446 
00447   real distance_modulus = 5 * log10(distance/10.);
00448   PRC(distance_modulus);
00449   PRL(distance);
00450 
00451 //  magnitude_limit -= distance_modulus;
00452 //  real magnitude_limit = t_obs/10. - distance_modulus;
00453 
00454 //  real luminosity_limit = pow(10, (4.76-magnitude_limit)/5.5); // in V
00455 //  PRC(magnitude_limit);
00456 //  PRL(luminosity_limit);
00457   
00458   real pos_to_parsec = b->get_starbase()->conv_r_dyn_to_star(1)
00459                      * cnsts.parameters(Rsun)/cnsts.parameters(parsec);
00460   real pos_to_arcsec = b->get_starbase()->conv_r_dyn_to_star(1)
00461                      * 3600 * cnsts.parameters(Rsun)
00462                      / (distance*cnsts.parameters(parsec));
00463   
00464 
00465   PRC(pos_to_parsec);PRL(pos_to_arcsec);
00466 
00467   real xpos, ypos, zpos;
00468   real M_max = VERY_LARGE_NUMBER;
00469   real local_Mmm=0, magn;
00470   real luminosity, L_max = 0;
00471   real xmax=0, ymax=0;
00472   vector r;
00473   if (b->get_oldest_daughter()) {
00474 
00475     vector r_com  = b->get_pos() - dc_pos;
00476 
00477     for_all_leaves(dyn, b, bb) {
00478 
00479 //      cerr << " new star: ";
00480 //      cerr << bb->get_index()<<endl;
00481 
00482       r = bb->get_pos()-bb->get_parent()->get_pos();
00483 //      PRL(r);
00484 
00485       switch(project) {
00486         case -3: xpos =  r[0];
00487                  ypos =  r[1];
00488                  zpos = -r[2];
00489                  break;
00490         case -2: xpos = -r[0];
00491                  ypos =  r[2];
00492                  zpos = -r[1];
00493                  break;
00494         case -1: xpos = -r[1];
00495                  ypos =  r[2];
00496                  zpos = -r[0];
00497                  break;
00498         case 1: xpos = r[1];
00499                 ypos = r[2];
00500                 zpos = r[0];
00501                 break;
00502         case 2: xpos = r[0];
00503                 ypos = r[2];
00504                 zpos = r[1];
00505                 break;
00506         case 3: xpos = r[0];
00507                 ypos = r[1];
00508                 zpos = r[2];
00509                 break;
00510       }
00511       xpos = xpos * pos_to_arcsec + half_xccd - xoffset;
00512       ypos = ypos * pos_to_arcsec + half_yccd - yoffset;
00513       zpos *= pos_to_parsec;
00514 //      PRC(zpos);
00515       if(distance+zpos>0) {
00516         real local_distance_modulus = 5 * log10((distance+zpos)/10.);
00517 //      PRL(local_distance_modulus);
00518 
00519         luminosity = get_luminosity(bb, band, local_distance_modulus,
00520                                     maximum_electrons/upper_Llimit);
00521 
00522 //      PRL(luminosity);
00523         if(L_max<luminosity) {
00524           L_max = luminosity;
00525           M_max = 4.76 - 2.5*log10(luminosity) - local_distance_modulus;
00526           local_Mmm = local_distance_modulus;
00527           xmax = xpos;    //ascsec
00528           ymax = ypos;
00529         }
00530 
00531         if (luminosity<=0) {
00532           luminosity = 0;
00533           cerr << "Stellar luminosity = " << luminosity << endl;
00534           cerr << "        star Not added to ccd"<<endl;
00535         }
00536         else {
00537           if (verbose) {
00538             real nx = xpos/arcsec_per_pixel;
00539             real ny = ypos/arcsec_per_pixel;
00540             if (nx>=-10 && nx<=XCCD_MAX && 
00541                 ny>=-10 && ny<=YCCD_MAX+10) {
00542               cerr << "Cluster star #" << bb->get_index() 
00543                    << " pos (x, y): " 
00544                    << nx << " " << ny << " pixels" << endl; 
00545               cerr << "             magnitudes (M, m): "  
00546                    << 4.76 - 2.5*log10(luminosity)  - local_distance_modulus
00547                    << " " << 4.76 - 2.5*log10(luminosity) <<endl;
00548             }
00549           }
00550           add_star_to_ccd(ccd, luminosity, xpos, ypos, beta_PSF, 
00551                           arcsec_per_pixel, fwhm);
00552         }
00553       }
00554     }
00555 
00556     cerr << "standard (brightest) star: \n"; 
00557     cerr << "L (app) = " << L_max << ", Mag (abs) = " << M_max << endl;
00558     cerr << "          local (M-m) = " << local_Mmm << endl;
00559     cerr << "    position in CCD = (" << floor(xmax/arcsec_per_pixel) << ", "
00560                                       << floor(ymax/arcsec_per_pixel) 
00561          << ") pixels"<<endl;
00562     cerr << "    position on sky = (" << xmax << ", "<<ymax 
00563          << ") arcsec."<<endl; 
00564 
00565     real t_exposure = calibrate_exposure_time(upper_Llimit,
00566                                               distance_modulus);
00567     PRL(t_exposure);
00568 
00569     if(add_background_stars) {
00570       cerr << "add background " <<endl;
00571       int n_backgr = add_background_stars_to_ccd(ccd, band, beta_PSF,
00572                                                  arcsec_per_pixel, fwhm,
00573                                                  verbose); 
00574       PRL(n_backgr);
00575     }
00576     else {
00577       cerr <<"no background stars added"<<endl;
00578     }
00579 
00580     if(add_standard_star) {
00581       cerr << "add standard star " <<endl;
00582       add_standard_stars(ccd, band, beta_PSF, arcsec_per_pixel, fwhm, verbose);
00583     }
00584     else {
00585       cerr <<"no standard star added" <<endl;
00586     }
00587 
00588     // initialize random processes.
00589     int actual_seed;
00590     if(input_seed==0) actual_seed = 0;
00591     actual_seed = srandinter(input_seed);
00592     PRC(input_seed);PRL(actual_seed);
00593 
00594     real Mmax = 0;
00595     for(int ix = 0; ix<XCCD_MAX; ix++) 
00596       for(int iy = 0; iy<YCCD_MAX; iy++)  
00597         Mmax = max(Mmax, ccd[ix][iy]);
00598 
00599     PRC(Mmax);PRL(upper_Llimit);
00600 //    real upper_limit_counts = calibrate_upper_limit(beta_PSF, upper_Llimit);
00601 //    PRL(upper_limit_counts);
00602     // Normalize and account for dynamic range of log10(4)
00603     real lmax = 0;
00604     for(int ix = 0; ix<XCCD_MAX; ix++) 
00605       for(int iy = 0; iy<YCCD_MAX; iy++)  {
00606         ccd[ix][iy] = ccd[ix][iy]/upper_Llimit;
00607         lmax = max(lmax, ccd[ix][iy]);
00608       }
00609     PRL(lmax);
00610 
00611     Mmax = 0;
00612     for(int ix = 0; ix<XCCD_MAX; ix++) 
00613       for(int iy = 0; iy<YCCD_MAX; iy++)  {
00614         ccd[ix][iy] *= maximum_electrons;
00615         Mmax = max(Mmax, ccd[ix][iy]);
00616       }
00617     PRL(Mmax);
00618 
00619     // add Scintilation noise of exposure duration
00620     real scintilation = 10./sqrt(t_exposure); // electrons
00621     for(int ix = 0; ix<XCCD_MAX; ix++) 
00622       for(int iy = 0; iy<YCCD_MAX; iy++)  
00623         ccd[ix][iy] += scintilation;
00624 
00625     // add dark current and readout
00626     real dark_current = 50*t_exposure;  // electrons
00627     real sky_background = 150;    // Gilliland et al. 1995, ApJ 447, 191
00628     for(int ix = 0; ix<XCCD_MAX; ix++) 
00629       for(int iy = 0; iy<YCCD_MAX; iy++)  {
00630         ccd[ix][iy] += dark_current;
00631         ccd[ix][iy] += sky_background;
00632       }
00633 
00634     // add Electroluminescence only on very cheap ccds
00635 //    real r_origin, electroluminescence = 10*t_exposure;
00636 //  real diagonal = sqrt(pow(XCCD_MAX, 2) + pow(YCCD_MAX, 2));
00637 //    for(int ix = 0; ix<XCCD_MAX; ix++) 
00638 //      for(int iy = 0; iy<YCCD_MAX; iy++)  {
00639 //      r_origin = sqrt(pow(ix, 2) + pow(iy, 2))
00640 //                 / diagonal;
00641 //      ccd[ix][iy] += electroluminescence*pow(1-r_origin, 4);
00642 //      }
00643 
00644     // add Thermal luminosity
00645 //    real readout = 200;
00646 //    for(int ix = 0; ix<XCCD_MAX; ix++) 
00647 //      for(int iy = 0; iy<YCCD_MAX; iy++)  {
00648 //      r_origin = (YCCD_MAX-iy)/YCCD_MAX;
00649 //      ccd[ix][iy] += readout*(1-r_origin);
00650 //      }
00651 
00652     // add Poissonian noise
00653     for(int ix = 0; ix<XCCD_MAX; ix++) 
00654       for(int iy = 0; iy<YCCD_MAX; iy++)  
00655         ccd[ix][iy] += sqrt(ccd[ix][iy])*gauss();
00656 //      ccd[ix][iy] += abs(sqrt(ccd[ix][iy])*gauss());
00657 
00658     // add Bleeding and Blooming
00659     create_overexposure_marks(ccd, maximum_electrons);
00660 
00661     // convert electrons to ADUs.
00662     for(int ix = 0; ix<XCCD_MAX; ix++) 
00663       for(int iy = 0; iy<YCCD_MAX; iy++)  
00664         ccd[ix][iy] /= electrons_to_ADU;
00665 
00666     // cut off too low and too high values.
00667     for(int ix = 0; ix<XCCD_MAX; ix++) 
00668       for(int iy = 0; iy<YCCD_MAX; iy++)  
00669         ccd[ix][iy] = min(max(0., ccd[ix][iy]), 1.*SATURATION_LIMIT);
00670 
00671     if(add_cosmics) {
00672       int n_cosm = add_cosmic_rays(ccd, t_exposure, verbose);
00673       PRL(n_cosm);
00674     }
00675     else
00676       cerr << "No cosmics added"<<endl;
00677 
00678     int n_bc = 0;
00679     if(nbad_column>0) {
00680       add_bad_column(ccd, nbad_column, verbose);
00681     }
00682     else
00683       cerr << "No bad columns added"<<endl;
00684 
00685     print_ccd(ccd, filename, t_exposure);
00686   }
00687 }
00688 
00689 // void mk_ccd.C
00690 //
00691 // Options:    -A    number of electrons to ADU [3]
00692 //             -B    filter of observation [3]
00693 //                   (options are: U=0, B=1, V=2, R=3, I=4) 
00694 //             -b    add background stars to ccd [false]
00695 //             -c    add cosmics rays to ccd [false]
00696 //             -d    distance to cluster in parsec [1000]
00697 //             -F    output filename [ccd.fits]
00698 //             -L    upper luminosity limit in Lsun [1]
00699 //             -N    add number of bad columns [0]
00700 //             -P    Kolmogorov point spread function beta [5]
00701 //             -p    give projecttion [1]
00702 //                       -3: project on xy plane viewed from -z
00703 //                       -2: project on xz plane viewed from -y
00704 //                       -1: project on yz plane viewed from -x
00705 //                        1: project on yz plane viewed from  x
00706 //                        2: project on xz plane viewed from  y
00707 //                        3: project on xy plane viewed from  z
00708 //             -R    reddening [0]
00709 //             -S    random number seed [clock]
00710 //             -s    add standard stars [false];
00711 //             -x    x-offset from density center [0]
00712 //             -y    y-offset from density center [0]
00713 //             -v    verbose, prints stars and positions to cerr [false]
00714 //
00715 //
00716 main(int argc, char ** argv) {
00717     check_help();
00718 
00719     wavelength band = F;
00720 
00721     bool verbose = false;
00722 
00723     int input_seed=0;
00724     int nbad_column = 0;
00725 
00726     int nx_bin = 512; // one pixel = 0.076 arcsec
00727     int ny_bin = 512;
00728 
00729     bool add_background_stars = false;
00730     bool add_standard_star = false;
00731     bool add_cosmics = false;
00732 
00733     real arcsec_per_pixel = 0.3;
00734     real fwhm  = 0.7;
00735 
00736     real distance = 1000;   //pc
00737     real reddening = 0;
00738     real electrons_to_ADU = 3;     // standard for modern CCD
00739     real beta_PSF = 5;             // standard PSF vary between 3 and 10
00740 
00741     real upper_luminosity_limit = 1; //Lsun
00742 
00743     real xoffset = 0;  // offset from cluster density center in arcsec
00744     real yoffset = 0;  // offset from cluster density center in arcsec
00745 
00746     int project = 1; // project along x(1), y(2), z(3)
00747 
00748     char* filename = "ccd.fits";
00749     extern char *poptarg;
00750     int c;
00751     char* param_string = "A:a:B:bcx:y:d:F:f:P:R:sS:L:x:y:N:v";
00752 
00753     while ((c = pgetopt(argc, argv, param_string)) != -1)
00754         switch(c)
00755             {
00756             case 'A': electrons_to_ADU = atof(poptarg);
00757                       break;
00758             case 'a': arcsec_per_pixel = atof(poptarg);
00759                       break;
00760             case 'f': fwhm = atof(poptarg);
00761                       break;
00762             case 'B': band = (wavelength)atoi(poptarg);
00763                       break;
00764             case 'b': add_background_stars = true;
00765                       break;
00766             case 'c': add_cosmics = true;
00767                       break;
00768             case 'p': project = atoi(poptarg);
00769                       break;
00770             case 'd': distance = atof(poptarg);
00771                       break;
00772             case 'P': beta_PSF = atof(poptarg);
00773                       break;
00774             case 'R': reddening = atof(poptarg);
00775                       break;
00776             case 'S': input_seed = atoi(poptarg);
00777                       break;
00778             case 's': add_standard_star = true;
00779                       break;
00780             case 'N': nbad_column = atoi(poptarg);
00781                       break;
00782             case 'L': upper_luminosity_limit = atof(poptarg);
00783                       break;
00784             case 'F': filename = poptarg;
00785                       break;
00786             case 'x': xoffset = atof(poptarg);   
00787                       break;
00788             case 'y': yoffset = atof(poptarg);
00789                       break;
00790             case 'v': verbose = true;
00791                       break;
00792             case '?': params_to_usage(cerr, argv[0], param_string);
00793                       get_help();
00794                       exit(1);
00795             }
00796 
00797     real distance_modulus = 5 * log10(distance/10.);
00798     real Mbol = 4.76;
00799     real magn = Mbol - 2.5*log10(upper_luminosity_limit) + distance_modulus;
00800     upper_luminosity_limit = pow(10, 0.4*(Mbol-magn));
00801     PRC(distance_modulus);PRC(magn);PRL(upper_luminosity_limit);
00802 
00803 
00804 //    ofstream outfile(filename, ios::out);
00805 //    ofstream outfile(filename, ios::binary);
00806 //    if (!outfile) {
00807 //      cerr << "error: couldn't crate file "<< filename<<endl;
00808 //      exit(0);
00809 //    }
00810 
00811     dyn *b = NULL;
00812     int count = 0;
00813     bool cod, try_com = false;
00814     vector dc_pos = 0;
00815     while (b = get_dyn(cin)) {
00816 
00817         b->flatten_node();
00818 
00819         cout << "\n\nTime = "
00820              << b->get_starbase()->conv_t_dyn_to_star(b->get_system_time())
00821              << endl;
00822 
00823         if (find_qmatch(b->get_dyn_story(), "density_center_pos")) {
00824           cerr << "found density_center_pos"<<endl;
00825 
00826            if (getrq(b->get_dyn_story(), "density_center_time")
00827                != b->get_system_time()) {
00828                warning("mkpovfile: neglecting out-of-date density center");
00829                try_com = true;
00830             } else
00831             cod = true;
00832 
00833             dc_pos = getvq(b->get_dyn_story(), "density_center_pos");
00834 
00835           PRL(dc_pos);
00836          }
00837 
00838          if (try_com && find_qmatch(b->get_dyn_story(), "com_pos")) {
00839           cerr << "found com_pos"<<endl;
00840 
00841             if (getrq(b->get_dyn_story(), "com_time")
00842                != b->get_system_time()) {
00843 
00844                warning("lagrad: neglecting out-of-date center of mass");
00845             } else
00846                 dc_pos = getvq(b->get_dyn_story(), "com_pos");
00847 
00848           PRL(dc_pos);
00849          }
00850 
00851         cerr << "Create CCD"<<endl;
00852         mk_ccd(b, dc_pos, project, band, distance, reddening, upper_luminosity_limit, xoffset, yoffset, electrons_to_ADU, beta_PSF, arcsec_per_pixel, fwhm, filename, add_background_stars, add_standard_star, input_seed, add_cosmics, nbad_column, verbose);
00853 
00854        rmtree(b);
00855     }
00856 }
00857 
00858 #endif

Generated at Sun Feb 24 09:57:07 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001