Beispiel #1
0
void advanced_manualcomm (void)
{
	int	m_manual_comm, m_comm_now, m_new_dates;

	m_manual_comm = MANUAL_COMM;
	m_comm_now = 1;
	m_new_dates = 0;

	m_manual_comm = !m_manual_comm;
	askYN ("Contact PrimeNet server automatically", &m_manual_comm);
	m_manual_comm = !m_manual_comm;
	askYN ("Contact PrimeNet server now", &m_comm_now);
	askYN ("Send new expected completion dates to server", &m_new_dates);

	if (askOkCancel ()) {
		if ((MANUAL_COMM && !m_manual_comm) ||
		    (!MANUAL_COMM && m_manual_comm)) {
			MANUAL_COMM = m_manual_comm;
			IniWriteInt (INI_FILE, "ManualComm", MANUAL_COMM);
			set_comm_timers ();
		}
		if (m_new_dates) UpdateEndDates ();
		if (m_comm_now) do_manual_comm_now ();
	}
}
Beispiel #2
0
void test_welcome (void)
{
	int	m_join = 1;

/* Set global flag indicating startup is in progress.  This will delay */
/* starting any communication with the server until the user has confirmed */
/* he wants to use primenet and he has selected his work preferences. */
	
	STARTUP_IN_PROGRESS = 1;

	outputLongLine ("\nWelcome to GIMPS, the hunt for huge prime numbers.  You will be asked a few simple questions and then the program will contact the primenet server to get some work for your computer.  Good luck!\n");
	outputLongLine ("\nAttention OVERCLOCKERS!!  Mprime has gained a reputation as a useful stress testing tool for people that enjoy pushing their hardware to the limit.  You are more than welcome to use this software for that purpose.  Please select the stress testing choice below to avoid interfering with the PrimeNet server.  Use the Options/Torture Test menu choice for your stress tests.  Also, read the stress.txt file.\n");
	outputLongLine ("\nIf you want to both join GIMPS and run stress tests, then Join GIMPS and answer the questions.  After the server gets some work for you, stop mprime, then run mprime -m and choose Options/Torture Test.\n\n");
	askYN ("Join Gimps? (Y=Yes, N=Just stress testing)", &m_join);
	if (m_join) {
		STRESS_TESTER = 0;
		IniWriteInt (INI_FILE, "StressTester", 0);
		USE_PRIMENET = 1;
		IniWriteInt (INI_FILE, "UsePrimenet", 1);
		test_primenet ();
		if (USE_PRIMENET && STARTUP_IN_PROGRESS) options_cpu ();
		if (USE_PRIMENET && STARTUP_IN_PROGRESS) test_worker_threads ();
		if (USE_PRIMENET && STARTUP_IN_PROGRESS) {
			STARTUP_IN_PROGRESS = 0;
			set_comm_timers ();
			linuxContinue (NULL, ALL_WORKERS, FALSE);
		} else
			STARTUP_IN_PROGRESS = 0;
	} else {
		STRESS_TESTER = 1;
		IniWriteInt (INI_FILE, "StressTester", 1);
		USE_PRIMENET = 0;
		IniWriteInt (INI_FILE, "UsePrimenet", USE_PRIMENET = 0);
		STARTUP_IN_PROGRESS = 0;
		torture ();
	}
	main_menu ();
}
Beispiel #3
0
int main()
{
    char filein[NCMAX], fileout[NCMAX], filestart[NCMAX],
        filebeam[NCMAX], description[NCMAX],
        filecross[NCMAX], cline[NCMAX];
  
    const char version[] = "21-nov-2012 (ejk)";

    int lstart=0, lpartl=0, lbeams=0, lwobble=0, lcross=0, nwobble=1;
    int ix, iy, iz, nx, ny, nz, nzout, ixmid, iymid, i, nslic0, islice,
        nacx,nacy, iqx, iqy, iwobble, ndf, idf, nbout, ib,
        ncellx, ncelly, ncellz, iycross, ns, NPARAM;
    int *hbeam, *kbeam;
    int natom, *Znum, *Znum2, istart, na, done, status, multiMode;
    long nbeams, nillum;
    long  ltime;
    unsigned long iseed;
    long32 nxl, nyl;   /*  tiffsubs 32 bit integer type */

    float *x, *y, *z, *occ, *wobble;
    float *x2, *y2, *z2, *occ2;
   
    float wmin, wmax, xmin,xmax, ymin, ymax, zmin, zmax;

    float *kx, *ky, *xpos, *ypos, *param, *sparam;
    float k2, k2max, scale, v0, mm0, wavlen, rx, ry,
        ax, by, cz, pi, rmin, rmax, aimin, aimax,
        rx2,ry2, ctiltx, ctilty, tctx, tcty,
        acmin, acmax, Cs3, Cs5, df, df0, sigmaf, dfdelt, aobj,
        qx, qy, qy2, q2, q2min, q2max, sumdf, pdf, k2maxo,
        temperature, ycross, dx, dy;

    float tr, ti, wr, wi;

    float **wave0r, **wave0i, **pix, **depthpix,
        *propxr, *propxi, *propyr, *propyi;

    cfpix wave;            /* complex probe wave functions */
    cfpix trans;           /* complex transmission functions */
    cfpix temp ;           /* complex scratch wavefunction */

    double sum, timer, xdf, chi0, chi1, chi2, chi3, t, zslice,
        deltaz, phirms, rsq, vz, alx, aly;
        
    FILE *fp1;

    floatTIFF myFile;

/*  echo version date and get input file name */

    printf("autoslic(e) version dated %s\n", version);
    printf("Copyright (C) 1998-2012 Earl J. Kirkland\n" );
    printf( "This program is provided AS-IS with ABSOLUTELY NO WARRANTY\n "
        " under the GNU general public license\n\n" );

    printf("perform CTEM multislice with automatic slicing and FFTW\n");
#ifdef USE_OPENMP
    printf( "and multithreaded using openMP\n");
#endif
    printf( "\n" );
    
    pi = (float) (4.0 * atan( 1.0 ));
    NPARAM = myFile.maxParam();
    param = (float*) malloc1D( NPARAM, sizeof(float), "param" );
    sparam = (float*) malloc1D( NPARAM, sizeof(float), "sparam" );
    for( ix=0; ix<NPARAM; ix++ ) param[ix] = 0.0F;

    printf("Name of file with input atomic "
           "potential in x,y,z format:\n");
    ns = scanf("%s", filein );

/*  get simulation options */

    printf("Replicate unit cell by NCELLX,NCELLY,NCELLZ :\n");
    ns = scanf("%d %d %d", &ncellx, &ncelly, &ncellz);
    if( ncellx < 1 ) ncellx = 1;
    if( ncelly < 1 ) ncelly = 1;
    if( ncellz < 1 ) ncellz = 1;

    printf("Name of file to get binary output of multislice result:\n");
    ns = scanf("%s", fileout );

    lpartl = askYN("Do you want to include partial coherence");

    if( lpartl == 1 ) {
        printf("Illumination angle min, max in mrad:\n");
        ns = scanf("%f %f", &acmin, &acmax);
        acmin  = acmin  * 0.001F;
        acmax  = acmax  * 0.001F;
        printf("Spherical aberration Cs3, Cs5(in mm.):\n");
        ns = scanf("%g %g", &Cs3, &Cs5);
        param[pCS]  = (float) ( Cs3*1.0e7 );
        param[pCS5] = (float) ( Cs5*1.0e7 );
        printf("Defocus, mean, standard deviation, and"
               " sampling size (in Angstroms) =\n");
        ns = scanf("%f %f %f", &df0, &sigmaf, &dfdelt);
        param[pDEFOCUS] = (float) df0;
        printf("Objective aperture (in mrad) =\n");
        ns = scanf("%f", &aobj);
        aobj = aobj * 0.001F;
#ifdef MANY_ABERR
    /*   get higher order aberrations if necessary */
    printf("type higher order aber. name (as C32a, etc.) followed\n"
        " by a value in mm. (END to end)\n");
    done = multiMode = 0;
    do{
        ns = scanf( "%20s", cline );
        if( strstr( cline, "END" ) != NULL ) {
            done = 1;
        } else {
            ns = scanf( "%lg", &vz );
            status = readCnm( cline, param, vz );        
            if( status < 0 ) {
                printf( "unrecognized aberration, exit...\n");
                exit( EXIT_SUCCESS );
            } else multiMode = 1;
        }
    } while( !done );

#endif
        lstart = 0;
    } else {
        printf("NOTE, the program image must also be run.\n");
        lstart = askYN("Do you want to start from previous result");
    }

    if ( lstart == 1 ) {
        printf("Name of file to start from:\n");
        ns = scanf("%s", filestart);
    } else {
        printf("Incident beam energy in kev:\n");
        ns = scanf("%g", &v0);
        printf("Wavefunction size in pixels, Nx,Ny:\n");
        ns = scanf("%d %d", &nx, &ny );
    }

    printf("Crystal tilt x,y in mrad.:\n");
    ns = scanf("%f %f", &ctiltx, &ctilty);
    ctiltx = ctiltx /1000;
    ctilty = ctilty /1000;

    /*  remember that the slice thickness must be > atom size
        to use projected atomic potential */
    printf("Slice thickness (in Angstroms):\n");
    ns = scanf("%lf", &deltaz );
    if( deltaz < 1.0 ) {
        printf("WARNING: this slice thickness is probably too thin"
            " for autoslice to work properly.\n");
    }

    if( lpartl == 0 ) {
        lbeams = askYN("Do you want to record the (real,imag) value\n"
        " of selected beams vs. thickness");
        if( lbeams == 1 ) {
            printf("Name of file for beams info:\n");
            ns = scanf("%s", filebeam );
            printf("Number of beams:\n");
            ns = scanf("%d", &nbout);
            if( nbout<1 ) nbout = 1;
            hbeam = (int*) malloc1D( nbout, sizeof(int), "hbeam" );
            kbeam = (int*) malloc1D( nbout, sizeof(int), "kbeam" );
            for( ib=0; ib<nbout; ib++) {
                printf("Beam %d, h,k=\n", ib+1);
                ns = scanf("%d %d", &hbeam[ib], &kbeam[ib] );
            }
        }
    }

    lwobble = askYN("Do you want to include thermal vibrations");
    if( lwobble == 1 ) {
        printf( "Type the temperature in degrees K:\n");
        ns = scanf( "%g", &temperature );
        printf( "Type number of configurations to average over:\n");
        ns = scanf( "%d", &nwobble );
        if( nwobble < 1 ) nwobble = 1;
        /* get random number seed from time if available 
            otherwise ask for a seed */
        ltime = (long) time( NULL );
        iseed = (unsigned) ltime;
        if( ltime == -1 ) {
            printf("Type initial seed for random number generator:\n");
            ns = scanf("%ld", &iseed);
        } else
            printf( "Random number seed initialized to %ld\n", iseed );
    } else temperature = 0.0F;

    if( lpartl == 0 ) {
        lcross = askYN("Do you want to output intensity vs. depth cross section");
        if( lcross == 1 ){
            printf( "Type name of file to get depth profile image:\n");
            ns = scanf("%s", filecross );
            printf( "Type y position of depth cross section (in Ang.):\n");
            ns = scanf("%f", &ycross );
        }
    }

/* start timing the actual computation just for fun */

    timer = cputim();
#ifdef USE_OPENMP
    walltimer = walltim();  /* wall time for opneMP */
#endif

/*  get starting value of transmitted wavefunction if required
   (this can only be used in coherent mode)
    remember to save params for final output pix  */

    if ( lstart == 1 ) {
        if( myFile.read( filestart ) != 1 ) {
            printf("Cannot open input file: %s .\n", filestart ); 
            exit( 0 );
        }

        if( myFile.getnpix() != 2 ) {
           printf("Input file %s must be complex, can't continue.\n",
               filestart );
           exit( 0 );
        }

        nx =  myFile.nx();
        ny =  myFile.ny();

        wave0r = (float**) malloc2D( nx, ny, sizeof(float), "waver" );
        nx = nx/2;
        wave0i = wave0r + nx;

        //  save starting pix for later
        for( ix=0; ix<nx; ix++) for( iy=0; iy<ny; iy++) {
                wave0r[ix][iy] = myFile(ix,iy);
                wave0i[ix][iy] = myFile(ix+nx,iy);
        }

        //  save parameters to verify successive images are same size etc.
        for( i=0; i<NPARAM; i++) sparam[i] = myFile.getParam( i );

        ax = sparam[pDX] * nx;
        by = sparam[pDY] * ny;
        v0     = sparam[pENERGY];
        nslic0 = (int) sparam[pNSLICES];
        printf("Starting pix range %g to %g real\n"
               "           %g to %g imag\n",
               sparam[pRMIN], sparam[pRMAX], sparam[pIMIN], sparam[pIMAX] );
        printf("Beam voltage = %g kV\n", v0);
        printf("Old crystal tilt x,y = %g, %g mrad\n", 1000.*sparam[pXCTILT],
            1000.*sparam[pYCTILT]);

    } else nslic0 = 0;     /* end if( lstart...) */

/*  calculate relativistic factor and electron wavelength */

    mm0 = 1.0F + v0/511.0F;
    wavlen = (float) wavelength( v0 );
    printf("electron wavelength = %g Angstroms\n", wavlen);

/*  read in specimen coordinates and scattering factors */

    natom = ReadXYZcoord( filein, ncellx, ncelly, ncellz,
        &ax, &by, &cz, &Znum, &x, &y, &z, &occ, &wobble,
        description, NCMAX );

    printf("%d atomic coordinates read in\n", natom );
    printf("%s", description );

    printf("Size in pixels Nx, Ny= %d x %d = %d beams\n",
           nx,ny, nx*ny);
    printf("Lattice constant a,b = %12.4f, %12.4f\n", ax,by);

    /*  calculate the total specimen volume and echo */
    xmin = xmax = x[0];
    ymin = ymax = y[0];
    zmin = zmax = z[0];
    wmin = wmax = wobble[0];

    for( i=0; i<natom; i++) {
        if( x[i] < xmin ) xmin = x[i];
        if( x[i] > xmax ) xmax = x[i];
        if( y[i] < ymin ) ymin = y[i];
        if( y[i] > ymax ) ymax = y[i];
        if( z[i] < zmin ) zmin = z[i];
        if( z[i] > zmax ) zmax = z[i];
        if( wobble[i] < wmin ) wmin = wobble[i];
        if( wobble[i] > wmax ) wmax = wobble[i];
    }
    printf("Total specimen range is\n %g to %g in x\n"
           " %g to %g in y\n %g to %g in z\n", xmin, xmax,
           ymin, ymax, zmin, zmax );
    if( lwobble == 1 )
        printf("Range of thermal rms displacements (300K) = %g to %g\n",
            wmin, wmax );
    
#ifdef USE_OPENMP
    /*  force LUT init. to avoid redundant init in parallel form */ 
    rsq = 0.5;  /* arbitrary position */   
    for( i=0; i<natom; i++) vz =  vzatomLUT( Znum[i], rsq );
#endif

/*  calculate spatial frequencies and positions for future use */

    rx = 1.0F/ax;
    rx2= rx*rx;
    ry = 1.0F/by;
    ry2= ry*ry;
    ixmid = nx/2;
    iymid = ny/2;
    nxl = nx;
    nyl = ny;

    kx   = (float*) malloc1D( nx, sizeof(float), "kx" );
    kx2  = (float*) malloc1D( nx, sizeof(float), "kx2" );
    xpos = (float*) malloc1D( nx, sizeof(float), "xpos" );
    freqn( kx, kx2, xpos, nx, ax );

    ky   = (float*) malloc1D( ny, sizeof(float), "ky" );
    ky2  = (float*) malloc1D( ny, sizeof(float), "ky2" );
    ypos = (float*) malloc1D( ny, sizeof(float), "ypos" );
    freqn( ky, ky2, ypos, ny, by );

/*  allocate some more arrays and initialize wavefunction */

    trans.resize( nx, ny );
    trans.init();

    wave.resize( nx, ny );
    wave.copyInit( trans );

    if( lstart == 0 ) {
        for( ix=0; ix<nx; ix++)
        for( iy=0; iy<ny; iy++) {
            wave.re(ix,iy) = 1.0F;  /*  real part */
            wave.im(ix,iy) = 1.0F;  /*  imag part */
        }
    } else {
        for( ix=0; ix<nx; ix++)
        for( iy=0; iy<ny; iy++) {
            wave.re(ix,iy) = wave0r[ix][iy];  /*  real part */
            wave.im(ix,iy) = wave0i[ix][iy];  /*  imag part */
        }
    }

    if( lcross == 1 ) {
        /* nz may be too small with thermal vibrations so add a few extra */
        nz = (int) ( (zmax-zmin)/ deltaz + 3.5);
        depthpix = (float**) malloc2D( nx, nz,
            sizeof(float), "depthpix" );
        for( ix=0; ix<nx; ix++)
        for( iz=0; iz<nz; iz++)  depthpix[ix][iz] = 0.0F;
        iycross = (int) ( 0.5 + (ny * ycross / by));
        while( iycross < 0 ) iycross += ny;
        iycross = iycross%ny;  /* make periodic in ny */
        printf("save xz cross section at iy= %d pixels\n", iycross );
    }

 /*  calculate propagator function  */
 
    k2max = nx/(2.0F*ax);
    tctx = ny/(2.0F*by);
    if( tctx < k2max ) k2max = tctx;
    k2max = BW * k2max;
    printf("Bandwidth limited to a real space resolution of %f Angstroms\n",
                     1.0F/k2max);
    printf("   (= %.2f mrad)  for symmetrical anti-aliasing.\n",
         wavlen*k2max*1000.0F);
    k2max = k2max*k2max;

    tctx = (float) (2.0 * tan(ctiltx));
    tcty = (float) (2.0 * tan(ctilty));
    
    propxr = (float*) malloc1D( nx, sizeof(float), "propxr" );
    propxi = (float*) malloc1D( nx, sizeof(float), "propxi" );
    propyr = (float*) malloc1D( ny, sizeof(float), "propyr" );
    propyi = (float*) malloc1D( ny, sizeof(float), "propyi" );

    scale = pi * ((float)deltaz);

    for( ix=0; ix<nx; ix++) {
        t = scale * ( kx2[ix]*wavlen - kx[ix]*tctx );
        propxr[ix] = (float)  cos(t);
        propxi[ix] = (float) -sin(t);
    }
    for( iy=0; iy<ny; iy++) {
        t = scale * ( ky2[iy]*wavlen - ky[iy]*tcty );
        propyr[iy] = (float)  cos(t);
        propyi[iy] = (float) -sin(t);
    }


/*  iterate the multislice algorithm proper

   NOTE: zero freg is in the bottom left corner and
     expands into all other corners - not in the center
     this is required for the FFT - don't waste time rearranging

  partial coherence method
   force the integrals to include the origin and to be symmetric
   about the origin and to have the same periodic boundary
   conditions as the sampling grid
*/
    if( lpartl == 1 ) {

        printf("Illumination angle sampling (in mrad) = %f, %f\n\n",
            1000.*rx*wavlen, 1000.*ry*wavlen);

        pix = (float**) malloc2D( nx, ny, sizeof(float), "pix" );
        for( ix=0; ix<nx; ix++)
        for( iy=0; iy<ny; iy++) pix[ix][iy] = 0.0F;
        
        temp.resize( nx, ny );
	temp.copyInit( trans );

        ndf = (int) ( ( 2.5F * sigmaf ) / dfdelt );

        nacx = (int) ( ( acmax / ( wavlen * rx ) ) + 1.5F );
        nacy = (int) ( ( acmax / ( wavlen * ry ) ) + 1.5F );

        q2max = acmax / wavlen;
        q2max = q2max*q2max;

        q2min = acmin / wavlen;
        q2min = q2min*q2min;

        k2maxo = aobj / wavlen;
        k2maxo = k2maxo*k2maxo;

        chi1 = pi * wavlen;
        chi2 = 0.5 * Cs3 * wavlen *wavlen;
        chi3 = Cs5 * wavlen*wavlen*wavlen*wavlen /3.0;
        nillum = 0;

        /* for Monte Carlo stuff */
        x2      = (float*) malloc1D( natom, sizeof(float), "x2" );
        y2      = (float*) malloc1D( natom, sizeof(float), "y2" );
        z2      = (float*) malloc1D( natom, sizeof(float), "z2" );
        occ2    = (float*) malloc1D( natom, sizeof(float), "occ2" );
        Znum2   =   (int*) malloc1D( natom, sizeof(int), "Znum2" );

        if( lwobble == 0 )
            sortByZ( x, y, z, occ, Znum, natom );

/*  integrate over the illumination angles */

        for( iwobble=0; iwobble<nwobble; iwobble++) {
            if( lwobble == 1 ) printf("configuration # %d\n", iwobble+1 );
            for( iqy= -nacy; iqy<=nacy; iqy++) {
                qy = iqy * ry;
                qy2 = qy * qy;
        
                for( iqx= -nacx; iqx<=nacx; iqx++) {
                    qx = iqx * rx;
                    q2 = qx*qx + qy2;
        
                    if( (q2 <= q2max) && (q2 >= q2min) ) {
                        nillum += 1;
                        for( ix=0; ix<nx; ix++) {
                            for( iy=0; iy<ny; iy++) {
                                t = 2.0*pi*( qx*xpos[ix] + qy*ypos[iy] );
                                wave.re(ix,iy) = (float) cos(t);  /* real */
                                wave.im(ix,iy) = (float) sin(t);  /* imag */
                            }
                        }
                        /*  add random thermal displacements scaled by temperature
                                if requested 
                            remember that initial wobble is at 300K for each direction */
                        if( lwobble == 1 ){
                            scale = (float) sqrt(temperature/300.0) ;
                            for( i=0; i<natom; i++) {
                                x2[i] = x[i] + (float)(wobble[i]*rangauss(&iseed)*scale);
                                y2[i] = y[i] + (float)(wobble[i]*rangauss(&iseed)*scale);
                                z2[i] = z[i] + (float)(wobble[i]*rangauss(&iseed)*scale);
                                occ2[i] = occ[i];
                                Znum2[i] = Znum[i];
                            }
                            printf( "Sorting atoms by depth...\n");
                            sortByZ( x2, y2, z2, occ2, Znum2, natom );
                            zmin = z2[0];       /* reset zmin/max after wobble */
                            zmax = z2[natom-1];
                            printf("Thickness range with thermal displacements"
                                   " is %g to %g (in z)\n", zmin, zmax );
                        } else for( i=0; i<natom; i++) {
                            x2[i] = x[i];
                            y2[i] = y[i];
                            z2[i] = z[i];
                            occ2[i] = occ[i];
                            Znum2[i] = Znum[i];
                        }
            
                        zslice = 0.75*deltaz;  /*  start a little before top of unit cell */
                        istart = 0;
            
                        while( istart < natom ) {
            
                            /* find range of atoms for current slice */
                            na = 0;
                            for(i=istart; i<natom; i++) 
                            if( z2[i] < zslice ) na++; else break;
            
                            /* calculate transmission function, skip if layer empty */
                            if( na > 0 ) {
                                trlayer( &x2[istart], &y2[istart], &occ2[istart],
                                    &Znum2[istart],na, ax, by, v0, 
                                    trans,  nxl, nyl, &phirms, &nbeams, k2max );
                
                                wave *= trans;  // transmit
                            }
            
                            /* remember: prop needed here to get anti-aliasing
                                    right */
 			    wave.fft();
                            propagate( wave, propxr, propxi,
                                propyr, propyi,
                                kx2,  ky2,  k2max, nx, ny );
			    wave.ifft();
            
                            zslice += deltaz;
                            istart += na;
            
                        } /* end while(zslice<=..) */
          
                        scale = 1.0F / ( ((float)nx) * ((float)ny) );
                        sum = 0.0;
                        for( ix=0; ix<nx; ix++) {
                            for( iy=0; iy<ny; iy++)
                                sum += wave.re(ix,iy)*wave.re(ix,iy)
                                    + wave.im(ix,iy)*wave.im(ix,iy);
                        }
                        sum = sum * scale;
             
                        printf("Illumination angle = %7.3f, %7.3f mrad",
                            1000.*qx*wavlen, 1000.*qy*wavlen);
                        printf(", integrated intensity= %f\n", sum );
            
                        /*-------- integrate over +/- 2.5 sigma of defocus ------------ */
    
                        wave.fft();
                        sumdf = 0.0F;
            
                        for( idf= -ndf; idf<=ndf; idf++) {
                            param[pDEFOCUS] = df = df0 + idf*dfdelt;
            
                            for( ix=0; ix<nx; ix++) {
                                alx = wavlen * kx[ix];  /* x component of angle alpha */
                                for( iy=0; iy<ny; iy++) {
                                    aly = wavlen * ky[iy];  /* y component of angle alpha */
                                    k2 = kx2[ix] + ky2[iy];
                                    if( k2 <= k2maxo ) {
                                        chi0 = (2.0*pi/wavlen) * chi( param, 
                                                alx, aly, multiMode );
                                        tr = (float)  cos(chi0);
                                        ti = (float) -sin(chi0);
                                        wr = wave.re(ix,iy);
                                        wi = wave.im(ix,iy);
                                        temp.re(ix,iy) = wr*tr - wi*ti;
                                        temp.im(ix,iy) = wr*ti + wi*tr;
                                    } else {
                                        temp.re(ix,iy) = 0.0F;  /* real */
                                        temp.im(ix,iy) = 0.0F;  /* imag */
                                    }
                                }  /*  end for( iy=0... ) */
                            }   /*  end for( ix=0... ) */

                            temp.ifft();
            
                            xdf = (double) ( (df - df0) /sigmaf );
                            pdf = (float) exp( -0.5F * xdf*xdf );
                            sumdf += pdf;
            
                            for( ix=0; ix<nx; ix++) {
                                for( iy=0; iy<ny; iy++) {
                                    wr = temp.re(ix,iy);
                                    wi = temp.im(ix,iy);
                                    pix[ix][iy] += pdf* ( wr*wr + wi*wi );
                                }
                            }
            
                        }/* end for(idf..) */
                    }/* end if( q2...) */
        
                } /* end for( iqx..) */
            } /* end for( iqy..) */
        } /* end for( iwobble...) */


        printf("Total number of illumination angle = %ld\n",
                nillum);
        printf("Total number of defocus values = %d\n", 2*ndf+1);
        /*  remember that nillum already includes nwobble so don't
             divide by nwobble! */
        scale = 1.0F / ( ((float)nillum) * sumdf );
        rmin  = pix[0][0] * scale;
        rmax  = rmin;
        aimin = 0.0F;
        aimax = 0.0F;

        for( ix=0; ix<nx; ix++)
        for( iy=0; iy<ny; iy++) {
            pix[ix][iy] = pix[ix][iy] * scale;
            if( pix[ix][iy] < rmin ) rmin = pix[ix][iy];
            if( pix[ix][iy] > rmax ) rmax = pix[ix][iy];
        }

/* ---- start coherent method below ----------------
        (remember that waver,i[][] was initialize above) */

    } else {

        if( lbeams ==1 ) {
            fp1 = fopen( filebeam, "w" );
            if( NULL == fp1 ) {
                printf("can't open file %s\n", filebeam);
                exit(0);
            }
            fprintf( fp1, " (h,k) = " );
            for(ib=0; ib<nbout; ib++)
                fprintf(fp1," (%d,%d)", hbeam[ib], kbeam[ib]);
            fprintf( fp1, "\n" );
            fprintf( fp1, "nslice, (real,imag) (real,imag) ...\n\n");
            for( ib=0; ib<nbout; ib++) {
                if( hbeam[ib] < 0 ) hbeam[ib] = nx + hbeam[ib];
                if( kbeam[ib] < 0 ) kbeam[ib] = ny + kbeam[ib];
                if( hbeam[ib] < 0 ) hbeam[ib] = 0;
                if( kbeam[ib] < 0 ) kbeam[ib] = 0;
                if( hbeam[ib] > nx-1 ) hbeam[ib] = nx-1;
                if( kbeam[ib] > ny-1 ) kbeam[ib] = ny-1;
            }
        }

        /*  add random thermal displacements scaled by temperature if requested 
            remember that initial wobble is at 300K for each direction */
        if( lwobble == 1 ){
            scale = (float) sqrt(temperature/300.0) ;
            for( i=0; i<natom; i++) {
                x[i] += (float) (wobble[i] * rangauss( &iseed ) * scale);
                y[i] += (float) (wobble[i] * rangauss( &iseed ) * scale);
                z[i] += (float) (wobble[i] * rangauss( &iseed ) * scale);
            }
        }

        printf( "Sorting atoms by depth...\n");
        sortByZ( x, y, z, occ, Znum, natom );

        if( lwobble == 1 ){
            zmin = z[0];        /* reset zmin/max after wobble */
            zmax = z[natom-1];
            printf("Thickness range with thermal displacements"
                " is %g to %g (in z)\n", zmin, zmax );
        }

        scale = 1.0F / ( ((float)nx) * ((float)ny) );

        zslice = 0.75*deltaz;  /*  start a little before top of unit cell */
        istart = 0;
        islice = 1;

        while( (istart < natom) && ( zslice < (zmax+deltaz) ) ) {

            /* find range of atoms for current slice */
            na = 0;
            for(i=istart; i<natom; i++) 
            if( z[i] < zslice ) na++; else break;

            /* calculate transmission function, skip if layer empty */
            if( na > 0 ) {
                trlayer( &x[istart], &y[istart], &occ[istart],
                    &Znum[istart], na, ax, by, v0, trans,
                    nxl, nyl, &phirms, &nbeams, k2max );
    
                /*??? printf("average atompot comparison = %g\n", 
                           phirms/(wavlen*mm0) ); */
    
                wave *= trans;    //  transmit
            }       

            /*  bandwidth limit */
            wave.fft();
            if( lbeams== 1 )  {
                fprintf( fp1, "%5d", islice);
                for( ib=0; ib<nbout; ib++) 
                    fprintf(fp1, "%10.6f %10.6f",
                        scale*wave.re(hbeam[ib],kbeam[ib]),   /* real */
                        scale*wave.im(hbeam[ib],kbeam[ib]) ); /* imag */
                    fprintf( fp1, "\n");
            }
            /* remember: prop needed here to get anti-aliasing right */
            propagate( wave, propxr, propxi,
                propyr, propyi, kx2,  ky2,  k2max, nx, ny );
            wave.ifft();

            /* save depth cross section if requested */
            if( (lcross == 1) && (islice<=nz) ) {
                for( ix=0; ix<nx; ix++) {
                    depthpix[ix][islice-1] = 
                        wave.re(ix,iycross)*wave.re(ix,iycross)
                           + wave.im(ix,iycross)*wave.im(ix,iycross);
                }
                nzout = islice;
            }

            sum = 0.0;
            for( ix=0; ix<nx; ix++) {
                for( iy=0; iy<ny; iy++)
                    sum += wave.re(ix,iy)*wave.re(ix,iy) +
                        wave.im(ix,iy)*wave.im(ix,iy);
            }
            sum = sum * scale;

            printf("z= %f A, %ld beams, %d coord., \n"
               "     aver. phase= %f, total intensity = %f\n",
               zslice, nbeams, na, phirms, sum );

            zslice += deltaz;
            istart += na;
            islice++;

        } /* end while(istart<natom..) */
    
        rmin  = wave.re(0,0);
        rmax  = rmin;
        aimin = wave.im(0,0);
        aimax = aimin;

        for( ix=0; ix<nx; ix++) {
            for( iy=0; iy<ny; iy++) {
                wr = wave.re(ix,iy);
                wi = wave.im(ix,iy);
                if( wr < rmin ) rmin = wr;
                if( wr > rmax ) rmax = wr;
                if( wi < aimin ) aimin = wi;
                if( wi > aimax ) aimax = wi;
            }
        }

    } /* end else .. coherent section */

/*  output results and find min and max to echo
    remember that complex pix are stored in the file in FORTRAN
        order for compatibility */

    if( lstart == 1 )
        for( ix=0; ix<NPARAM; ix++ ) param[ix] = sparam[ix];
    param[pRMAX]  = rmax;
    param[pIMAX]  = aimax;
    param[pRMIN]  = rmin;
    param[pIMIN]  = aimin;
    param[pXCTILT]  = ctiltx;
    param[pYCTILT] = ctilty;
    param[pENERGY] = v0;
    param[pDX] = dx = (float) ( ax/((float)nx) );
    param[pDY] = dy = (float) ( by/((float)ny) );
    param[pWAVEL] = wavlen;
    param[pNSLICES] = 0.0F;  /* ??? */
    if ( lpartl == 1 ) {
        param[pDEFOCUS] = df0;
        param[pOAPERT] = aobj;
        param[pCAPERT] = acmax;
        param[pDDF] = sigmaf;
    }

    for( ix=0; ix<NPARAM; ix++ ) myFile.setParam( ix, param[ix] );

    if ( lpartl == 1 ) {
        myFile.resize( nx, ny );
        myFile.setnpix( 1 );
        for( ix=0; ix<nx; ix++) for( iy=0; iy<ny; iy++)
            myFile(ix,iy) = pix[ix][iy];
        i = myFile.write( fileout, rmin, rmax, aimin, aimax, dx, dy );

    } else {

        myFile.resize( 2*nx, ny );
        myFile.setnpix( 2 );
        for( ix=0; ix<nx; ix++) for( iy=0; iy<ny; iy++) {
            myFile(ix,iy)    = wave.re(ix,iy);
            myFile(ix+nx,iy) = wave.im(ix,iy);
        }

        i = myFile.write( fileout, rmin, rmax, aimin, aimax, dx, dy );
    }

    if( i != 1 ) printf( "autoslice cannot write TIF file %s\n",
            fileout );
    printf( "pix range %g to %g real,\n"
        "      %g to %g imag\n",  rmin,rmax,aimin,aimax );

    /*  output depth cross section if requested */
    if( lcross == 1 ){
        rmin  = depthpix[0][0];
        rmax  = rmin;

        for( ix=0; ix<nx; ix++)
        for( iz=0; iz<nzout; iz++) {
            wr = depthpix[ix][iz];
            if( wr < rmin ) rmin = wr;
            if( wr > rmax ) rmax = wr;
        }
        myFile.setParam( pRMAX, rmax );
        myFile.setParam( pIMAX, 0.0F );
        myFile.setParam( pRMIN, rmin );
        myFile.setParam( pIMIN, 0.0F );
        myFile.setParam( pDY, dy = (float) ( deltaz ) );

        myFile.resize( nx, nzout );
        myFile.setnpix( 1 );
        for( ix=0; ix<nx; ix++) for( iz=0; iz<nzout; iz++) {
            myFile(ix,iz) = depthpix[ix][iz];
        }
        i = myFile.write( filecross, rmin, rmax, aimin, aimax, dx, dy );

        if( i != 1 ) printf( "autoslice cannot write TIF file %s\n",
                filecross );
        printf( "depth pix range %g to %g real,\n",  rmin,rmax );
    }

    printf("Total CPU time = %f sec.\n", cputim()-timer );
#ifdef USE_OPENMP
    printf("wall time = %g sec.\n", walltim() - walltimer);
#endif

    return 0;

} /* end main() */
Beispiel #4
0
int main()
{
    char **filein, fileout[NCMAX];
    char datetime[20];

    int i, ipix, ix, iy, nx, ny, nxold, nyold, ixmid, iymid, npix, npixold,
        ninput, nsum, nh, logpix, ns, PowerSpectra, pixtype, NPARAM;
    long *nhist;

    float scale, pixc, rmin,rmin2,rmax, aimin,aimax,tr, ti, dx, dy;
    float *param;
    float  **pixr, **pixi, **pixout;
    double sum, *hist, ax, by, rx, ry2;

    FILE *fp;

    floatTIFF myFile;

    /*--------  get input file names etc. ------------ */
    printf( "sumpix version dated 6-nov-2012 ejk\n");
    printf("Copyright (C) 1998-2012 Earl J. Kirkland\n" );
    printf( "This program is provided AS-IS with ABSOLUTELY NO WARRANTY\n "
        " under the GNU general public license\n\n" );

     printf( "Sum multiple image or wave function files,\n"
        "complex images will be converted to squared "
        "magnitude before summing.\n");
    printf( "All input images must be the same type and size.\n\n" );
    printf( "Type number of input image files\n");
    ns = scanf( "%d", &ninput );
    filein = (char**) malloc2D( ninput, NCMAX, sizeof(char), "filein" );
    for( ipix=0; ipix<ninput; ipix++) {
        printf("input %d : ", ipix );
        ns = scanf("%s", filein[ipix] );
    }
    printf("\n");

    printf("Type name of output file:\n");
    ns = scanf( "%s", fileout );

    logpix = askYN( "Do you want to display on log scale");

    PowerSpectra = askYN( "Do you want to convert to a power spectra");

/* get image size and type from the first input pix
    all successive images have to be the same type and size !!! 
   -remember that floatTIFF cannot handle plain integer TIFF images

 -------- read floating point images and average --------

   remember that complex images are stacked side by side
    with npix=2 and nx twice its real value 
    (real images have npix=1 and nx its normal value)
*/
    NPARAM = myFile.maxParam();
    param = (float*) malloc1D( NPARAM, sizeof(float), "param" );

    for( ipix=0; ipix<ninput; ipix++) {

        for( ix=0; ix<NPARAM; ix++) param[ix] = 0.0F;
        if( myFile.read( filein[ipix] ) != 1 ) {
            printf("Cannot open file %s\n", filein[ipix] );
            exit( 0 );
        }
        myFile.getDateTime( datetime );
        nx = (int) myFile.nx();
        ny = (int) myFile.ny();
        npix = myFile.getnpix();
        if( 0 == ipix ) {
            npixold = npix;
            nxold = nx;
            nyold = ny;
            pixr = (float**) malloc2D( 2*nx, ny, sizeof(int), "pixr-1" );  //npix ????
            pixout = (float**) malloc2D( nx, ny, sizeof(int), "pixout-1" );
            for( ix=0; ix<nx; ix++) 
                for( iy=0; iy<ny; iy++) pixout[ix][iy] = 0.0F;
            pixtype = floatPIX;
            printf( "Image size : Nx= %d, Ny= %d\n", nx, ny );
        } else if( (nx != nxold) || (ny != nyold) ) {
            printf( "different size in file %s, "
                " nx= %d, ny= %d\n", filein[ipix], nx, ny );
            exit( 0 );
        }
        if( npix != npixold ) {
            printf( "Can't mix real and complex images"
                " in file: %s\n", filein[ipix] );
            exit( 0 );
        }
        if( (npix<1) || (npix>2) ) {
            printf( "bad npix = %d in TIFF file %s\n",
                npix, filein[ipix] );
            exit( 0 );
        }

        //  copy both real+imag back to old style array to re-use old code
        //        (not optimal but works for now)
        for( ix=0; ix<nx; ix++) for( iy=0; iy<ny; iy++)
                pixr[ix][iy] = myFile(ix,iy);

        nx = nx /npix;
        ax = myFile.getParam(pDX) * ((float)nx);
        by = myFile.getParam(pDY) * ((float)ny);
        rmin = myFile.getParam(pRMIN);
        rmax = myFile.getParam(pRMAX);
        aimin = myFile.getParam(pIMIN);
        aimax = myFile.getParam(pIMAX);
        if( npix == 2 ) {
            printf( "pix %d created %s, range: %g to %g (real),"
                "\n     and %g to %g (imag)\n",
                ipix, datetime, rmin, rmax, aimin, aimax);
        } else if( npix == 1 ) {
            printf( "pix %d created %s, range: %g to %g (real)\n",
                ipix, datetime, rmin, rmax );
        }
        if( PowerSpectra == 1 ) {
            if( npix == 1 ) {
                if( 0 == ipix )
                    pixi = (float**) malloc2D( nx, ny, sizeof(float),
                        "pixi-2" );
                for( ix=0; ix<nx; ix++) 
                    for( iy=0; iy<ny; iy++)   pixi[ix][iy] = 0.0F;
            } else if( (npix==2) && (ipix==0) ) pixi = pixr + nx;
            npix = 2;
            fft2d ( pixr, pixi, nx, ny, +1);
        }

        if( npix == 1 ) {       /* real pix */
            for( ix=0; ix<nx; ix++) 
            for( iy=0; iy<ny; iy++) 
                pixout[ix][iy] += pixr[ix][iy];
        } else if( npix == 2 ) {    /* complex pix */
            if( 0 == ipix ) pixi = pixr + nx;
            for( ix=0; ix<nx; ix++) 
            for( iy=0; iy<ny; iy++) {
                tr = pixr[ix][iy];
                ti = pixi[ix][iy];
                pixout[ix][iy] += ( tr*tr + ti*ti);
            }
        }

    }  // end for(ipix=... )
    

/*  Output results and find min and max to echo
     NOTE the logarithmic scaling of diffraction pattern
    is taken from Gonzalez and Wintz pg 48
    added scaling trick from showpix.f  9-aug-1995 ejk
*/
    printf("Output pix size : Nx= %d, Ny= %d\n", nx, ny );

    if( (PowerSpectra == 1) && ( pixtype == floatPIX ) ) {

        /* put (0,0) in the center */
        invert2D( pixout, nx, ny);

        /* histogram the azimutal average */
        hist = (double*) malloc1D( (nx+ny), sizeof(double), "hist" );
        nhist = (long*) malloc1D( (nx+ny), sizeof(long), "nhist" );
        for( ix=0; ix<(nx+ny); ix++) {
            hist[ix] = 0.0;
            nhist[ix] = 0;
        }

        scale = 1.0F / ( ((float)nx) * ((float)ny) );

        sum = 0.0;
        nsum = 0;
        nh = 0;
        ixmid = nx/2;
        iymid = ny/2;

        for( iy=0; iy<ny; iy++) {
            ry2 = (double) ( iy-iymid);
            ry2 = ry2*(ax/by);
            ry2 = ry2*ry2;
            for( ix=0; ix<nx; ix++) {
                pixc = pixout[ix][iy];
                rx = (double) (ix-ixmid);
                i = (int) ( sqrt( rx*rx + ry2 ) + 0.5);
                hist[i] += pixc;
                nhist[i]++;
                if( i > nh ) nh = i;
                if( logpix == 1 ) {
                    if( pixc > 1.e-10F)  pixc = 
                        (float) log( (double) fabs(pixc) );
                    else pixc = -23.0F;
                    pixout[ix][iy] = pixc;
                }
                if( (ix == 0) && (iy == 0) ) {
                    rmin = pixc;
                    rmax = rmin;
                } else if( (ix != ixmid) && (iy != iymid) ) {
                    if( pixc < rmin ) rmin = pixc;
                    if( pixc > rmax ) rmax = pixc;
                }
                if( (ix>(3*nx)/8) && (ix<(5*nx)/8) &&
                    (iy>(3*ny)/8) && (iy<(5*ny)/8) ) {
                    sum = sum + pixc;
                    nsum += 1;
                }

            }  /* end for ix... */
        } /* end for iy... */

        printf( "write azimuthal averaged intensity vs. \n"
            "  spatial frequency k, into file azimuth.dat\n");
        fp = fopen( "azimuth.dat", "w+" );
        if( fp == NULL ) {
            printf("cannot open file azimuthal.dat\n");
            exit( 0 );
        }
        for( i=0; i<=nh; i++) {
            hist[i] = hist[i] / nhist[i];
            fprintf( fp, "%16.8g  %16.8g\n", ((double)i)/ax,
                 hist[i] );
        }
        fclose( fp );

        myFile.resize( nx, ny );  // in case it was complex
	myFile.setnpix( 1 );
        myFile.setParam( pRMAX, rmax);
        myFile.setParam( pIMAX, aimax = 0.0F);
        myFile.setParam( pIMIN, aimin = 0.0F);
        myFile.setParam( pRMIN, rmin );
        myFile.setParam( pDX,  dx = 1.0F / ((float)ax) );
        myFile.setParam( pDY,  dy = 1.0F / ((float)by) );
        printf("output image size: %f to %f /Angstroms\n", nx*dx, ny*dy );
        printf("Power Spectra range %f to %f\n",  rmin, rmax );

        for( ix=0; ix<nx; ix++) for( iy=0; iy<ny; iy++)
            myFile(ix,iy) = pixout[ix][iy];
        rmin2= (float) (0.05*rmin + 0.95*sum/nsum);   //  somtimes better
        //myFile.write( fileout, rmin, rmax, aimin, aimax, dx, dy );
        myFile.write( fileout, rmin2, rmax, aimin, aimax, dx, dy );

    } else if(  (pixtype == floatPIX) && (PowerSpectra == 0) ) {

        for( iy=0; iy<ny; iy++) {
            for( ix=0; ix<nx; ix++) {
                pixc = pixout[ix][iy];
                if( logpix == 1 ) {
                    if( pixc > 1.e-30F)  pixc = 
                        (float) log( (double) fabs(pixc) );
                    else pixc = -100.0F;
                    pixout[ix][iy] = pixc;
                }
                if( (ix == 0) && (iy == 0) ) {
                    rmin = pixc;
                    rmax = rmin;
                } else {
                    if( pixc < rmin ) rmin = pixc;
                    if( pixc > rmax ) rmax = pixc;
                }

            }  /* end for ix... */
        } /* end for iy... */

        myFile.resize( nx, ny );  // in case it was complex
        myFile.setnpix( 1 );
        myFile.setParam( pRMAX, rmax);
        myFile.setParam( pIMAX, 0.0F);
        myFile.setParam( pIMIN, 0.0F);
        myFile.setParam( pRMIN, rmin);
        printf("Summed pix range %f to %f\n",  rmin, rmax );

        for( ix=0; ix<nx; ix++) for( iy=0; iy<ny; iy++)
            myFile(ix,iy) = pixout[ix][iy];
        dx = myFile.getParam( pDX );
        dy = myFile.getParam( pDY );
        aimin = aimax = 0.0F;
        myFile.write( fileout, rmin, rmax, aimin, aimax, dx, dy );

    }

    return EXIT_SUCCESS;

} /* end main() */
Beispiel #5
0
void options_preferences (void)
{
	unsigned long m_iter, m_r_iter, m_disk_write_time;
	unsigned long m_modem, m_retry, m_work, m_backup;
	float	m_end_dates;
	int	m_noise, m_battery;

	m_iter = ITER_OUTPUT;
	m_r_iter = ITER_OUTPUT_RES;
	m_disk_write_time = DISK_WRITE_TIME;
	m_modem = MODEM_RETRY_TIME;
	m_retry = NETWORK_RETRY_TIME;
	m_work = DAYS_OF_WORK;
	m_end_dates = DAYS_BETWEEN_CHECKINS;
	m_backup = NUM_BACKUP_FILES;
	m_noise = !SILENT_VICTORY;
	m_battery = RUN_ON_BATTERY;

	askNum ("Iterations between screen outputs", &m_iter, 1, 999999999);
	askNum ("Iterations between results file outputs",
		&m_r_iter, 10000, 999999999);
	askNum ("Minutes between disk writes", &m_disk_write_time, 10, 999999);
	if (USE_PRIMENET && DIAL_UP)
		askNum ("Minutes between modem retries", &m_modem, 1, 300);
	if (USE_PRIMENET)
		askNum ("Minutes between network retries", &m_retry, 1, 300);
	if (USE_PRIMENET)
		askNum ("Days of work to queue up", &m_work, 1, 90);
	if (USE_PRIMENET)
		askFloat ("Days between sending end dates", &m_end_dates, 0.125, 7);
	askNum ("Number of Backup Files", &m_backup, 1, 3);
	askYN ("Make noise if new Mersenne prime is found", &m_noise);
	askYN ("Run program even when using laptop battery power", &m_battery);

	if (askOkCancel ()) {
		ITER_OUTPUT = m_iter;
		ITER_OUTPUT_RES = m_r_iter;
		DISK_WRITE_TIME = m_disk_write_time;
		MODEM_RETRY_TIME = m_modem;
		NETWORK_RETRY_TIME = m_retry;
		DAYS_OF_WORK = m_work;
		DAYS_BETWEEN_CHECKINS = m_end_dates;
		NUM_BACKUP_FILES = m_backup;
		SILENT_VICTORY = !m_noise;
		if (RUN_ON_BATTERY != m_battery) {
			RUN_ON_BATTERY = m_battery;
			IniWriteInt (LOCALINI_FILE, "RunOnBattery", RUN_ON_BATTERY);
			run_on_battery_changed ();
		}
		IniWriteInt (INI_FILE, "OutputIterations", ITER_OUTPUT);
		IniWriteInt (INI_FILE, "ResultsFileIterations", ITER_OUTPUT_RES);
		IniWriteInt (INI_FILE, "DiskWriteTime", DISK_WRITE_TIME);
		IniWriteInt (INI_FILE, "NetworkRetryTime", MODEM_RETRY_TIME);
		IniWriteInt (INI_FILE, "NetworkRetryTime2", NETWORK_RETRY_TIME);
		IniWriteInt (INI_FILE, "DaysOfWork", DAYS_OF_WORK);
		IniWriteFloat (INI_FILE, "DaysBetweenCheckins", DAYS_BETWEEN_CHECKINS);
		IniWriteInt (INI_FILE, "NumBackupFiles", NUM_BACKUP_FILES);
		IniWriteInt (INI_FILE, "SilentVictory", SILENT_VICTORY);
		spoolMessage (PRIMENET_PROGRAM_OPTIONS, NULL);
	}
}
Beispiel #6
0
void test_primenet (void)
{
	int	m_primenet, m_dialup;
	unsigned long m_proxy_port, m_debug;
	char	m_userid[21], m_compid[21], m_proxy_host[121];
	char	m_proxy_user[51], m_proxy_pwd[51], orig_proxy_pwd[51];
	unsigned short proxy_port;
	int	update_computer_info, primenet_debug;
	char	m_username[81], m_userpwd[14];

	update_computer_info = FALSE;
	primenet_debug = IniSectionGetInt (INI_FILE, "PrimeNet", "Debug", 0);

	m_primenet = USE_PRIMENET;
	if (strcmp (USERID, "ANONYMOUS") == 0)
		m_userid[0] = 0;
	else
		strcpy (m_userid, USERID);
	strcpy (m_compid, COMPID);
	m_dialup = DIAL_UP;
	getProxyInfo (m_proxy_host, &proxy_port, m_proxy_user, m_proxy_pwd);
	m_proxy_port = proxy_port;
	strcpy (orig_proxy_pwd, m_proxy_pwd);
	m_debug = primenet_debug;

	askYN ("Use PrimeNet to get work and report results", &m_primenet);
	if (!m_primenet) goto done;

	outputLongLine ("\nYou must first create your user ID at mersenne.org or leave user ID blank to run anonymously.  See the readme.txt file for details.\n");
	askStr ("Optional user ID", m_userid, 20);
	askStr ("Optional computer name", m_compid, 20);

	askYN ("Computer uses a dial-up connection to the Internet", &m_dialup);

	askStr ("Optional proxy host name", m_proxy_host, 120);
	if (!m_proxy_host[0]) goto done;

	askNum ("Proxy port number", &m_proxy_port, 1, 65535);
	askStr ("Optional proxy user name", m_proxy_user, 50);
	askStr ("Optional proxy password", m_proxy_pwd, 50);
	askNum ("Output debug info to prime.log (0=none, 1=some, 2=lots)", &m_debug, 0, 2);

done:	if (askOkCancel ()) {
		DIAL_UP = m_dialup;
		IniWriteInt (INI_FILE, "DialUp", DIAL_UP);

		if (m_proxy_host[0] && m_proxy_port != 8080)
			sprintf (m_proxy_host + strlen (m_proxy_host), ":%lu", m_proxy_port);
		IniSectionWriteString (INI_FILE, "PrimeNet", "ProxyHost", m_proxy_host);
		if (m_proxy_host[0]) {
			IniSectionWriteString (INI_FILE, "PrimeNet", "ProxyUser", m_proxy_user);
			if (strcmp (m_proxy_pwd, orig_proxy_pwd)) {
				IniSectionWriteString (INI_FILE, "PrimeNet",
					"ProxyPass", m_proxy_pwd);
				IniSectionWriteInt (INI_FILE, "PrimeNet",
					"ProxyMask", 0);
			}
		}
		if (m_debug != primenet_debug) {
			IniSectionWriteInt (INI_FILE, "PrimeNet", "Debug",
					    m_debug);
		}

		if (m_userid[0] == 0)
			strcpy (m_userid, "ANONYMOUS");

		if (strcmp (USERID, m_userid) != 0) {
			strcpy (USERID, m_userid);
			sanitizeString (USERID);
			IniWriteString (INI_FILE, "V5UserID", USERID);
			update_computer_info = TRUE;
		}
		if (strcmp (COMPID, m_compid) != 0) {
			strcpy (COMPID, m_compid);
			sanitizeString (COMPID);
			IniWriteString (LOCALINI_FILE, "ComputerID", COMPID);
			update_computer_info = TRUE;
		}

		if (!USE_PRIMENET && m_primenet) {
			USE_PRIMENET = 1;
			create_window (COMM_THREAD_NUM);
			base_title (COMM_THREAD_NUM, "Communication thread");
			if (!STARTUP_IN_PROGRESS) set_comm_timers ();
			spoolMessage (PRIMENET_UPDATE_COMPUTER_INFO, NULL);
			spoolExistingResultsFile ();
		} else if (USE_PRIMENET && !m_primenet) {
			USE_PRIMENET = 0;
			if (!STARTUP_IN_PROGRESS) set_comm_timers ();
		} else if (update_computer_info)
			spoolMessage (PRIMENET_UPDATE_COMPUTER_INFO, NULL);

		IniWriteInt (INI_FILE, "UsePrimenet", USE_PRIMENET);
		spoolMessage (PRIMENET_PROGRAM_OPTIONS, NULL);
	} else
		STARTUP_IN_PROGRESS = 0;
}
Beispiel #7
0
int main() 
{
    int ix,iy, nx, ny, ixmid, iymid, ns,
        i, j, nsym, jj, iz, is, lwobble;
    int ncellx, ncelly, ncellz;
    long ncoeff, ltime;
    unsigned long iseed;

    char filein[NCMAX], fileot[NCMAX], cline[NCMAX];

    float *kx, *ky, *wobble;
    float rmin, rmax, imin, imax, dx, dy;
    float *symx1, *symx2, *symy1, *symy2;
    double scampr, scampi, sum, runtime, fe, ky2, k2, k2max,
        scale, ax,by,cz,total1, total2, rx2, ry2,
        temperature, scalet;

    cfpix cpix;     //  complex floating point image with FFTW

    FILE *fp;

    floatTIFF myFile;

/*  the following are the chemical symbols for the periodic table */

    const char symbol[] = {
        " HHeLiBe B C N O FNeNaMgAlSi P SCl"
        "Ar KCaScTi VCrMnFeCoNiCuZnGaGeAsSeBr"
        "KrRbSr YZrNbMoTcRuRhPdAgCdInSnSbTe"
        " IXeCsBaLaCePrNdPmSmEuGdTbDyHoErTm"
        "YbLuHfTa WReOsIrPtAuHgTlPbBiPoAtRn"
        "FrRaAcThPa UNpPuAmCmBkCfEsFmMdNoLr"
    };

    /*  Echo version date */
    printf("atompot version dated 26-apr-2014 EJK\n");
    printf("Copyright (C) 1998-2014 Earl J. Kirkland\n" );
    printf( "This program is provided AS-IS with ABSOLUTELY NO WARRANTY\n "
        " under the GNU general public license\n\n" );

    printf( "calculate projected atomic potentials (to use in multislice)\n");
    printf( "    using FFTW\n\n");

    /*  Get input file name etc. */
    printf("Name of file with input crystal data :\n");
    ns = scanf("%s", filein);

    printf("Name of file to get binary output"
          " of atomic potential :\n");
    ns = scanf("%s", fileot);

    printf("Real space dimensions in pixels Nx, Ny :\n");
    ns = scanf("%d %d", &nx, &ny);

    printf("Replicate unit cell by NCELLX,NCELLY,NCELLZ :\n");
    ns = scanf("%d %d %d", &ncellx, &ncelly, &ncellz);
    if( ncellx < 1 ) ncellx = 1;
    if( ncelly < 1 ) ncelly = 1;
    if( ncellz < 1 ) ncellz = 1;

/*  read in parameters for Monte Carlo displacements
      to simulate thermal motion 
    get the initial seed from the time counter if it exists
    otherwise ask user for a seed 
   - this should get a different random number sequence each time the
      program is run 
*/
    lwobble = askYN( "Do you want to add thermal displacements to atomic coord.?" );
    if( lwobble == 1 ) {
        printf("Temperature in degrees K:\n");
        ns = scanf("%lg", &temperature);
        ltime = (long) time( NULL );
        iseed = (unsigned) ltime;
        if( ltime == -1 ) {
            printf("Type initial seed for random number generator:\n");
            ns = scanf("%ld", &iseed);
        } else
            printf( "Random number seed initialized to %ld\n", iseed );
    }

/*  start timer */

    runtime = cputim();

/*  Start to read in specimen parameters
    remember to use fgets() in ReadLine() and NOT fscanf() 
    because fscanf() ignores newlines and 
        we need to sync on whole lines
*/

    fp = fopen( filein,"r" );
    if( fp == NULL ) {
        perror(" can't open crystal data input file");
        exit(0 );
    }
    ReadLine( fp, cline, NCMAX, filein );
    ns = sscanf( cline, "%lf %lf %lf", &ax, &by, &cz);
    printf("2D lattice constants= %f x %f Angstroms\n"
        " and propagation constant= %f Angstroms\n",
           ax, by, cz );
    if( (ncellx > 1) || (ncelly > 1) || (ncellz > 1 ) ) {
        ax = ax * ncellx;
        by = by * ncelly;
        cz = cz * ncellz;
        printf("Unit cell replicated to a= %g, b= %g, c=%g  Angstroms\n",
           ax, by, cz );
    }

    /* read in symmetry operations */

    ReadLine( fp, cline, NCMAX, filein );
    ns = sscanf( cline, "%d", &nsym);
    if( nsym > 0 ) {
        symx1 = (float*) malloc1D( nsym, sizeof(float), "symx1" );
        symx2 = (float*) malloc1D( nsym, sizeof(float), "symx2" );
        symy1 = (float*) malloc1D( nsym, sizeof(float), "symy1" );
        symy2 = (float*) malloc1D( nsym, sizeof(float), "symy2" );
        for( i=0; i<nsym; i++)  {
            ReadLine( fp, cline, NCMAX, filein );
            ns = sscanf( cline, "%f %f %f %f",
                &symx1[i], &symx2[i], &symy1[i], &symy2[i]);
       }
    }

/*  Calculate misc constants (Nx*Ny added because FFT2D
    performs scaling) also adjust k2max for circular symmetry
    remember that k2max is still in units of Angstroms
*/
    k2max = 2.0*ax/nx;
    scale = 2.0*by/ny;
    if( scale > k2max ) k2max =scale;

    printf("Maximum symmetrical resolution set to %g Angstroms\n",
           k2max );
    k2max = 1.0 / (k2max * k2max);

    rx2 = (1.0/ax);  rx2 = rx2*rx2;
    ry2 = (1.0/by);  ry2 = ry2*ry2;
    scale = ( ((double)nx) * ((double)ny) ) /(ax*by);
    ixmid = nx/2;
    iymid = ny/2;

    ky = (float*) malloc1D( ny , sizeof(float), "ky" );
    kx = (float*) malloc1D( nx , sizeof(float), "kx" );

    /*  will only need half of these but doesn't take much CPU */
    for( iy=0; iy<ny; iy++) {
        if( iy < iymid )  ky[iy] = (float) iy;
        else ky[iy] = (float)(iy-ny);
    }

    for( ix=0; ix<nx; ix++) {
        if( ix < ixmid )  kx[ix] = (float) ix;
        else kx[ix] = (float)(ix-nx);
    }

    //  allocate arrays
    cpix.resize( nx, ny/2+1 );

    cpix.init( 2 );   //  complex to real transform estimate mode - fast init, slow execution

    for( ix=0; ix<nx; ix++) 
    for( iy=0; iy<=iymid;iy++)  {
        cpix.re(ix,iy) = 0.0F;  /* real */
        cpix.im(ix,iy) = 0.0F;  /* imag */
    }

    /* ---- alloc misc arrays ----- */
    x      = (float*) malloc1D( NAMAX, sizeof(float), "x" );
    y      = (float*) malloc1D( NAMAX, sizeof(float), "y" );
    occ    = (float*) malloc1D( NAMAX, sizeof(float), "occ" );
    wobble = (float*) malloc1D( NAMAX, sizeof(float), "wobble" );

    /* ------ read in actual coordinates ------ */

    total2 = 0.0;
    printf("\n");
More:
        ReadLine( fp, cline, NCMAX, filein );
        iz = -1;    /* reset because some machines leave last value */
        ns = sscanf( cline, "%d", &iz);
        if( (strlen(cline) > 1) && (iz >= 1) && (iz <= NZMAX) ) {
            j = 0;
            total1 = 0.0;
            while( ReadLine( fp, cline, NCMAX, filein ) > 2 ) {
                ns = sscanf( cline, "%f %f %f %f", &occ[j], &x[j], &y[j], &wobble[j] );
                total1 = total1 +  occ[j] * (nsym+1) * ncellx * ncelly;
                if( nsym > 0) {
                    if( (j+nsym+1) > NAMAX) {
                        printf("Too many atoms\n");
                        printf("  Maximum allowed = %d\n",NAMAX);
                        fclose( fp );
                        exit(0);

                    }
                    for( jj=0; jj<nsym; jj++) {
                        occ[j+jj+1] = occ[j];
                        wobble[j+jj+1] = wobble[j];
                        x[j+jj+1] = (symx1[jj]*x[j] +symx2[jj] )/ncellx;
                        y[j+jj+1] = (symy1[jj]*y[j] +symy2[jj] )/ncelly;
                    }
                }
 
                x[j] = x[j] /ncellx;
                y[j] = y[j] /ncelly;
                j = j + nsym + 1;
                if( j > NAMAX ) {
                    printf("Too many atoms\n");
                    printf("  Maximum allowed = %d\n",NAMAX);
                    fclose( fp );
                    exit( 0 );
                }
            }  /* end while( ReadLine()>2 */

            natom = j ;
            is = 2*(iz-1);
            printf("%8.2f atoms with Z= %3d (%c%c)\n",
              total1, iz, symbol[is], symbol[is+1]);

            /*   if thermal vibrations are requested then we must expand
                ncellx,y here otherwise factor it inside scamp() 
                (its faster)
                 add random displacements to all positions
           */
            if( lwobble == 1 ) {
                if( (j-1)*ncellx*ncelly > NAMAX) {
                    printf("Too many atoms\n");
                    printf("  maximum allowed = %d\n",NAMAX);
                    exit( 0 );
                }

                if( ncellx > 1) {
                    for( ix=1; ix<ncellx; ix++)
                    for( i=0; i<natom; i++) {
                        x[j] = x[i] + ((float)ix)/((float)ncellx);
                        y[j] = y[i];
                        wobble[j] = wobble[i];
                        occ[j++] = occ[i];
                    }
                    natom = j - 1;
                }

                if( ncelly > 1) {
                    for( iy=1; iy<ncelly; iy++)
                    for( i=0; i<natom; i++) {
                        x[j] = x[i];
                        y[j] = y[i] + ((float)iy)/((float)ncelly);
                        wobble[j] = wobble[i];
                        occ[j++] = occ[i];
                    }
                    natom = j - 1;
                }

                /* scale thermal displacements to 300 deg. K 
                     and normalize to 3D - integrating over the z direction */
                scalet = sqrt( temperature / 300.0 );
                for( i=0; i<natom; i++) {
                    x[i] = x[i] + 
                        (float) (wobble[i] * scalet * rangauss( &iseed ) /ax);
                    y[i] = y[i] + 
                        (float) (wobble[i] * scalet * rangauss( &iseed ) /by);
                }

                nsx = 1;
                nsy = 1;

            } else {
                nsx = ncellx;
                nsy = ncelly;

            }  /* end if( lwobble == TRUE ) */

/*  calculate scattering amplitude in upper half plane (FFTW)
   NOTE zero freg is in the bottom left corner and
     expands into all other corners - not in the center
     this is required for FFT, high freq is in the center

    - add extra complex conjugation to correct for the opposite
    sign convention used by FFTW

*/
            ncoeff = 0;
            for( iy=0; iy<=iymid; iy++) {
                ky2 = ky[iy]*ky[iy] * ry2;
                for( ix=0; ix<nx; ix++) {
                    k2 = kx[ix]*kx[ix] * rx2 + ky2;
                    if( k2 <= k2max) {
                        fe = scale * featom( iz, k2 );
                        scamp( kx[ix], ky[iy], &scampr, &scampi ) ;
                        cpix.re(ix,iy) += (float) (scampr * fe);  // real  === bad here ???
                        cpix.im(ix,iy) += (float) (-scampi * fe); // imag 
                        ncoeff++;
                    }

                }  /* end for(ix */
            } /* end for(iy */

            total2 = total2 + total1;
            goto More;
            
        }  /* end top if( iz>= 1) */
        
    /*  end loop over types */

    printf("\n   for a grand total of %10.2f atoms\n", total2);
    fclose( fp );

    cpix.ifft();   /*    inverse fft */

    /*  output results and find min and max to echo */

    if( nsym > 0 ) {
        free( symx1 );
        free( symx2 );
        free( symy1 );
        free( symy2 );
    }

    /*  copy to floatTIFF pix to output with */
    myFile.resize( nx, ny );
    myFile.setnpix( 1 );
    rmin = rmax = cpix.rre(0,0);
    sum = 0.0;

    for( iy=0; iy<ny; iy++) {
        for( ix=0; ix<nx; ix++) {
            myFile(ix,iy) = cpix.rre(ix,iy);
            sum += myFile(ix,iy);
            if( myFile(ix,iy) < rmin ) rmin = myFile(ix,iy);
            if( myFile(ix,iy) > rmax ) rmax = myFile(ix,iy);
        }
    }

    myFile.zeroParam();
    myFile.setParam( pRMAX, rmax);
    myFile.setParam( pRMIN,  rmin);
    myFile.setParam( pC, (float) cz);
    myFile.setParam( pRES, (float) (1.0/sqrt(k2max)) );
    myFile.setParam( pDX,  dx = (float) ax / ((float)nx) );
    myFile.setParam( pDY,  dy = (float) by / ((float)ny) );

    imin = imax = 0;
    if( myFile.write( fileot, rmin,rmax, imin,imax, dx, dy ) != 1 )
        printf( "atompot cannot write an output file.\n");

    printf(" pix range %g to %g\n", rmin, rmax);
    printf("%ld fourier coeff. calculated in right half plane\n",
           ncoeff);
    printf("The average real space value was %g\n",
           sum /(((float)nx)*((float)ny)));
          
    printf("CPU time (excluding set-up) = %f sec.\n", cputim()-runtime );

    return EXIT_SUCCESS;

}  /* end main() */