Ejemplo n.º 1
0
/* sleeps # of seconds */
void esleep(double seconds_to_sleep)
{
    struct timeval tval;
    static double clk_tck_val = 0;
    double total = seconds_to_sleep;	/* total sleep asked for */
    double started = etime();	/* time when called */
    double left = total;
    if (seconds_to_sleep <= 0.0)
	return;
    if (clk_tck_val <= 0) {
	clk_tck_val = clk_tck();
    }
    do {
	if (left < clk_tck_val && esleep_use_yield) {
	    sched_yield();
	} else {
	    tval.tv_sec = (long) left;	/* double->long truncates, ANSI */
	    tval.tv_usec = (long) ((left - (double) tval.tv_sec) * 1000000.0);
	    if (tval.tv_sec == 0 && tval.tv_usec == 0) {
		tval.tv_usec = 1;
	    }
	    if (select(0, NULL, NULL, NULL, &tval) < 0) {
		if (errno != EINTR) {
		    break;
		}
	    }
	}
	left = total - etime() + started;
    }
    while (left > 0 && (left > clk_tck_val && esleep_use_yield));
    return;
}
Ejemplo n.º 2
0
/*!
    Refreshes the content.
 */
void QxtProgressLabel::refresh()
{
    // elapsed
    qreal elapsed = 0;
    if (qxt_d().start.isValid())
        elapsed = qxt_d().start.elapsed() / 1000.0;
    QTime etime(0, 0);
    etime = etime.addSecs(static_cast<int>(elapsed));

    // percentage
    qreal percent = 0;
    if (qxt_d().cachedMax != 0)
        percent = (qxt_d().cachedVal - qxt_d().cachedMin) / static_cast<qreal>(qxt_d().cachedMax);
    qreal total = 0;
    if (percent != 0)
        total = elapsed / percent;

    // remaining
    QTime rtime(0, 0);
    rtime = rtime.addSecs(static_cast<int>(total - elapsed));

    // format
    QString tformat = qxt_d().tformat;
    if (tformat.isEmpty())
        tformat = tr("mm:ss");
    QString cformat = qxt_d().cformat;
    if (cformat.isEmpty())
        cformat = tr("ETA: %r");

    QString result = QString(cformat).replace("%e", etime.toString(tformat));
    result = result.replace("%r", rtime.toString(tformat));
    setText(result);
}
Ejemplo n.º 3
0
BOOL CAdduserDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	HICON hIcon=LoadIcon (AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_AddUser));
	SetIcon(hIcon,TRUE);

	//初始化登录时间控件
	CTime stime=CTime::GetCurrentTime (); 
	CTime etime( 2030, 12, 31, 23, 59, 59 ); 
	m_date.SetFormat("yyyy/MM/dd HH:mm:ss");
	m_date.SetRange(&stime,&etime);
	m_date.SetTime(&stime);

	//初始化端口与在线状态控件
	m_dtuport.SetWindowText ("5001");
	m_dscport.SetWindowText ("5002");
	m_status.SelectString (1,"在线");

	//初始化IP地址控件
	CString str1;
	str1=GetLocalIP();
	m_dtuip.SetWindowText (str1);
	m_dscip.SetWindowText (str1);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}
Ejemplo n.º 4
0
int _execute(char args[][ACOLS])
{
	char* cfgpath = NULL;

	if(!strcmp(EXIT, args[0]))
		run = 0;
	else if(!strcmp(EXPORT, args[0]))
		expenv(args);
	else if(!strcmp(ECHO, args[0]))
		echo_text(args);
	else if(!strcmp(ETIME, args[0]))
		etime(args);
	else if(!strcmp(LIMITS, args[0]))
		compute_limits(args);
	else if(!strcmp(CD, args[0]))
		chgdir(args);
	else if(!findexec(args, &cfgpath))
		otroexec(args, &cfgpath);

	if(cfgpath != NULL) free(cfgpath);

	return 0;
}
Ejemplo n.º 5
0
/* Write "n" bytes to a descriptor. */
int sendn(int fd, const void *vptr, int n, int _flags, double _timeout)
{
    int nleft;
    long nwritten;
    int select_ret;
    double start_time, current_time, timeleft;
    char *ptr;
    struct timeval timeout_tv;
    struct timeval timeout_tv_copy;
    fd_set send_fd_set;

    timeout_tv.tv_sec = (long) _timeout;
    timeout_tv.tv_usec = (long) (_timeout * 1000000.0);
    if (timeout_tv.tv_usec >= 1000000) {
	timeout_tv.tv_usec = timeout_tv.tv_usec % 1000000;
    }
    timeout_tv_copy = timeout_tv;
    FD_ZERO(&send_fd_set);
    FD_SET(fd, &send_fd_set);

    ptr = (char *) vptr;	/* can't do pointer arithmetic on void* */
    nleft = n;
    current_time = start_time = etime();
    timeleft = _timeout;
    while (nleft > 0) {
	if (fabs(_timeout) > 1E-6) {
	    if (_timeout > 0) {
		current_time = etime();
		timeleft = start_time + _timeout - current_time;
		if (timeleft <= 0.0) {
		    if (print_sendn_timeout_errors) {
			rcs_print_error
			    ("sendn(fd=%d, vptr=%p, int n=%d, int flags=%d, double _timeout=%f) timed out.\n",
			    fd, vptr, n, _flags, _timeout);
		    }
		    sendn_timedout = 1;
		    return -1;
		}
		timeout_tv.tv_sec = (long) timeleft;
		timeout_tv.tv_usec = (long) (timeleft * 1000000.0);
		if (timeout_tv.tv_usec >= 1000000) {
		    timeout_tv.tv_usec = timeout_tv.tv_usec % 1000000;
		}
		select_ret =
		    select(fd + 1, (fd_set *) NULL, &send_fd_set,
		    (fd_set *) NULL, &timeout_tv);
	    } else {
		select_ret =
		    select(fd + 1, (fd_set *) NULL, &send_fd_set,
		    (fd_set *) NULL, NULL);
	    }
	    switch (select_ret) {
	    case -1:
		rcs_print_error("Error in select: %d -> %s\n", errno,
		    strerror(errno));
		rcs_print_error
		    ("sendn(fd=%d, vptr=%p, int n=%d, int _flags=%d, double _timeout=%f) failed.\n",
		    fd, vptr, n, _flags, _timeout);
		return -1;

	    case 0:
		rcs_print_error
		    ("sendn(fd=%d, vptr=%p, int n=%d, int _flags=%d, double _timeout=%f) timed out.\n",
		    fd, vptr, n, _flags, _timeout);
		return -1;

	    default:
		break;
	    }
	}
	if ((nwritten = send(fd, ptr, nleft, _flags)) == -1) {
	    rcs_print_error("Send error: %d = %s\n", errno, strerror(errno));
	    return (-1);	/* error */
	}
	nleft -= nwritten;
	ptr += nwritten;
	if (nleft > 0 && _timeout > 0.0) {
	    current_time = etime();
	    if (current_time - start_time > _timeout) {
		rcs_print_error("sendn: timed out after %f seconds.\n",
		    current_time - start_time);
		return (-1);
	    }
	    esleep(0.001);
	}
    }
    rcs_print_debug(PRINT_SOCKET_WRITE_SIZE, "wrote %d bytes to %d\n", n, fd);
    return (n);
}
Ejemplo n.º 6
0
/* Function that sends to SUMA NIML formatted commands */  
int SendToSuma (COMM_STRUCT *cs, NI_group *ngru, int action)
{
   static char FuncName[]={"SendToSuma"};
   static float etm = 0.0;
   static int i_in = 0;
   char stmp[500];
   static struct  timeval tt;
   float *f=NULL;
   int n=-1, WaitClose, WaitMax, *ip = NULL;
   float wtm;
   int good = 1;
   int LocalHead = 0;
   
   /* fprintf (stderr, "%s: LocalHead = %d\n", FuncName, LocalHead); */
   
   if (action == 0) { /* initialization of connection */
      NI_element *nel = NULL;
      
      fprintf(stdout,"Setting up for communication with SUMA ...\n");
      cs->Send = 1;

      if (!niml_call (cs)) {
         fprintf (stderr,"Failed in SUMA_niml_call\n");
         /* connection flag is reset in SUMA_niml_call */
         cs->Send = 0;
         return(0);
      }

      nel = NI_new_data_element("StartTracking", 0); 
      cs->TrackID = 1; /* that's the index for StartTracking command */
      NI_set_attribute(nel,"ni_stream_name", cs->StreamName );
      sprintf(stmp, "%d", cs->TrackID);
      NI_set_attribute(nel,"Tracking_ID", stmp);
      if (NI_write_element( cs->NimlStream , 
                            nel, cs->comm_NI_mode ) < 0) {
         fprintf (stderr,"Failed to start tracking.\nContinuing...\n");
      } 
      if (nel) NI_free_element(nel); nel = NULL;
      
      /* start the workprocess for this program  */
      fprintf(stderr,"Here you can register the workprocess for listening\n"
                     "with your program's main loop. See the comments in \n"
                     "the main() function of this program regarding function\n"
                     "Hallo_niml_workproc()\n\n");
      ++i_in;
      return(1);
   }
   
   if (action == 1) { /* action == 1,  send data mode */
      if (!i_in) {
         fprintf (stderr,"You must call SUMA_SendToSuma with action 0 "
                     "before action 1.\nNo Communcation cleanup done.\n");
         cs->Send = 0;
         return(0);
      }
      if (!ngru) {
         fprintf (stderr,"Nothing to send!\n");
         return(0);
      }
      /* make sure stream is still OK */
      if (NI_stream_goodcheck ( cs->NimlStream , 1 ) < 0) {
         cs->GoneBad = 1;
         fprintf(stdout,"Communication stream gone bad.\n"
                      "Shutting down communication.\n");
         cs->Send = 0;
         return(1);  /* returning without error since program should continue */
      }

      /* add tracking (not that important)*/
      ++cs->TrackID;
      sprintf(stmp,"%d", cs->TrackID);
      NI_set_attribute (ngru, "Tracking_ID", stmp);
         
      
      #if NIML_DEBUG /* writes every element to a 
                        text file for debugging ... */
      {
         NI_stream ns;  
         /* Test writing results in asc, 1D format */ 
         if (LocalHead) fprintf(stderr," %s:-\nWriting ascii 1D ...\n"
                        , FuncName);
         /* open the stream */
         sprintf(stmp, "file:niml_dbg_asc_TID_%d_.1D",cs->TrackID);
         ns = NI_stream_open( stmp , "w" ) ;
         if( ns == NULL ){
           fprintf (stderr,"Error  %s:\nCan't open Test_write_asc_1D!\n"
                        , FuncName); 
            return(0);
         }

         /* write out the element */
         if (NI_write_element( ns , ngru ,
                               NI_TEXT_MODE | NI_HEADERSHARP_FLAG ) < 0) {
            fprintf (stderr,"Error  %s:\nFailed in NI_write_element\n"
                           , FuncName);
            return(0);
         }

         /* close the stream */
         NI_stream_close( ns ) ;
      }
      #endif

      if (cs->nelps > 0) { /* make sure that you are not sending 
                              elements too fast */
         if (!etm) {
            etm = 100000.0; /* first pass, an eternity */
            if (LocalHead) 
               fprintf (stdout,"%s: Initializing timer\n", FuncName);
            etime(&tt, 0);
         }
         else {
            if (LocalHead) 
               fprintf (stdout,"%s: Calculating etm\n", FuncName);
            etm = etime(&tt, 1);
         }
         wtm = 1./cs->nelps - etm;
         if (wtm > 0) { /* wait */
            if (LocalHead) 
               fprintf (stdout, 
                        "%s: Sleeping by %f to meet refresh rate...\n", 
                        FuncName, wtm);
            NI_sleep((int)(wtm*1000));
         }
      }

      /* send it to SUMA */
      if (LocalHead) 
         fprintf (stdout,"Sending element %d comm_NI_mode = %d...\n", 
                              cs->TrackID, cs->comm_NI_mode);
      if (NI_write_element(   cs->NimlStream , ngru, 
                              cs->comm_NI_mode ) < 0) {
         fprintf(stderr,"Failed updating SUMA...\n");
      }
      
      if (LocalHead) {
         if (cs->nelps > 0) 
            fprintf (stdout,
                     "        element %d sent (%f sec)\n", 
                     cs->TrackID, etime(&tt, 1));
         else fprintf (stdout,"        element %d sent \n", cs->TrackID);
      }
      
      if (cs->nelps > 0) {
         if (LocalHead) 
            fprintf (stdout,"%s: Resetting time...\n", FuncName);
         etime(&tt, 0); /* start the timer */
      }
      ++i_in;
      return(1);
   }/* action == 1 */
   
   if (action == 2) {
      NI_element *nel=NULL;
      if (i_in < 2) {
         fprintf (stderr,"You must call SUMA_SendToSuma with action 0 and 1"
                     " before action 2.\nNo Communcation cleanup done.\n");
         cs->Send = 0;
         return(0);
      }
      /* reset static variables */
         i_in = 0;
         etm = 0.0;
         
      /* close the stream*/
      if (cs->Send && !cs->GoneBad) { 
         /* stop tracking */
         nel = NI_new_data_element("StopTracking", 0);
         NI_set_attribute(nel,"ni_stream_name", cs->StreamName);

         if (NI_write_element( cs->NimlStream , nel, 
                               cs->comm_NI_mode ) < 0) {
            fprintf (stderr,"Failed to stop tracking.\nContinuing...\n");
         } 
         if (nel) NI_free_element(nel); nel = NULL;

         /* tell suma you're done with that stream */
         nel = NI_new_data_element("CloseKillStream",0);
         if (!nel) {
            fprintf (stderr,"Failed to create nel");
            return(0);
         }

         NI_set_attribute (nel, "ni_stream_name", cs->StreamName);
         if (NI_write_element( cs->NimlStream , nel, 
                               cs->comm_NI_mode ) < 0) {
                        fprintf (stderr,"Failed updating SUMA...\n");
         }
         if (nel) NI_free_element(nel) ; nel = NULL;


         /* now wait till stream goes bad */
         Wait_Till_Stream_Goes_Bad(cs, 1000, 5000, 1);
          
         NI_stream_close(cs->NimlStream);
         cs->NimlStream = NULL;
         cs->NimlStream_flag = 0;
         cs->TrackingID = 0;
         cs->Send = 0;
         cs->GoneBad = 0;
         cs->nelps = -1.0;
         cs->TrackID = 0;
      }
   
      return(1);
   }

   /* should not get here */
   fprintf (stderr,"Flow error.\nThis should not be\n");
   return(0);
}
Ejemplo n.º 7
0
/* init_comm_buffers() allocates and initializes the command,
   status, and error buffers used to communicate with the user
   space parts of emc.
*/
static int init_comm_buffers(void)
{
    int joint_num, n;
    emcmot_joint_t *joint;
    int retval;

    rtapi_print_msg(RTAPI_MSG_INFO,
	"MOTION: init_comm_buffers() starting...\n");

    emcmotStruct = 0;
    emcmotDebug = 0;
    emcmotStatus = 0;
    emcmotCommand = 0;
    emcmotConfig = 0;

    /* record the kinematics type of the machine */
    kinType = kinematicsType();

    /* allocate and initialize the shared memory structure */
    emc_shmem_id = rtapi_shmem_new(key, mot_comp_id, sizeof(emcmot_struct_t));
    if (emc_shmem_id < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    "MOTION: rtapi_shmem_new failed, returned %d\n", emc_shmem_id);
	return -1;
    }
    retval = rtapi_shmem_getptr(emc_shmem_id, (void **) &emcmotStruct);
    if (retval < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    "MOTION: rtapi_shmem_getptr failed, returned %d\n", retval);
	return -1;
    }

    /* zero shared memory before doing anything else. */
    memset(emcmotStruct, 0, sizeof(emcmot_struct_t));

    /* we'll reference emcmotStruct directly */
    emcmotCommand = &emcmotStruct->command;
    emcmotStatus = &emcmotStruct->status;
    emcmotConfig = &emcmotStruct->config;
    emcmotDebug = &emcmotStruct->debug;
    emcmotInternal = &emcmotStruct->internal;
    emcmotError = &emcmotStruct->error;

    /* init error struct */
    emcmotErrorInit(emcmotError);

    /* init command struct */
    emcmotCommand->head = 0;
    emcmotCommand->command = 0;
    emcmotCommand->commandNum = 0;
    emcmotCommand->tail = 0;
    emcmotCommand->spindlesync = 0.0;

    /* init status struct */
    emcmotStatus->head = 0;
    emcmotStatus->commandEcho = 0;
    emcmotStatus->commandNumEcho = 0;
    emcmotStatus->commandStatus = 0;

    /* init more stuff */

    emcmotDebug->head = 0;
    emcmotConfig->head = 0;

    emcmotStatus->motionFlag = 0;
    SET_MOTION_ERROR_FLAG(0);
    SET_MOTION_COORD_FLAG(0);
    SET_MOTION_TELEOP_FLAG(0);
    emcmotDebug->split = 0;
    emcmotStatus->heartbeat = 0;
    emcmotStatus->computeTime = 0.0;
    emcmotConfig->numJoints = num_joints;

    ZERO_EMC_POSE(emcmotStatus->carte_pos_cmd);
    ZERO_EMC_POSE(emcmotStatus->carte_pos_fb);
    emcmotStatus->vel = VELOCITY;
    emcmotConfig->limitVel = VELOCITY;
    emcmotStatus->acc = ACCELERATION;
    emcmotStatus->feed_scale = 1.0;
    emcmotStatus->spindle_scale = 1.0;
    emcmotStatus->net_feed_scale = 1.0;
    /* adaptive feed is off by default, feed override, spindle 
       override, and feed hold are on */
    emcmotStatus->enables_new = FS_ENABLED | SS_ENABLED | FH_ENABLED;
    emcmotStatus->enables_queued = emcmotStatus->enables_new;
    emcmotStatus->id = 0;
    emcmotStatus->depth = 0;
    emcmotStatus->activeDepth = 0;
    emcmotStatus->paused = 0;
    emcmotStatus->overrideLimitMask = 0;
    emcmotStatus->spindle.speed = 0.0;
    SET_MOTION_INPOS_FLAG(1);
    SET_MOTION_ENABLE_FLAG(0);
    emcmotConfig->kinematics_type = kinType;

    emcmotDebug->oldPos = emcmotStatus->carte_pos_cmd;
    ZERO_EMC_POSE(emcmotDebug->oldVel);

    emcmot_config_change();

    /* init pointer to joint structs */
#ifdef STRUCTS_IN_SHMEM
    joints = &(emcmotDebug->joints[0]);
#else
    joints = &(joint_array[0]);
#endif

    /* init per-joint stuff */
    for (joint_num = 0; joint_num < num_joints; joint_num++) {
	/* point to structure for this joint */
	joint = &joints[joint_num];

	/* init the config fields with some "reasonable" defaults" */

	joint->type = 0;
	joint->max_pos_limit = 1.0;
	joint->min_pos_limit = -1.0;
	joint->vel_limit = 1.0;
	joint->acc_limit = 1.0;
	joint->min_ferror = 0.01;
	joint->max_ferror = 1.0;
	joint->home_search_vel = 0.0;
	joint->home_latch_vel = 0.0;
	joint->home_final_vel = -1;
	joint->home_offset = 0.0;
	joint->home = 0.0;
	joint->home_flags = 0;
	joint->home_sequence = -1;
	joint->backlash = 0.0;

	joint->comp.entries = 0;
	joint->comp.entry = &(joint->comp.array[0]);
	/* the compensation code has -DBL_MAX at one end of the table
	   and +DBL_MAX at the other so _all_ commanded positions are
	   guaranteed to be covered by the table */
	joint->comp.array[0].nominal = -DBL_MAX;
	joint->comp.array[0].fwd_trim = 0.0;
	joint->comp.array[0].rev_trim = 0.0;
	joint->comp.array[0].fwd_slope = 0.0;
	joint->comp.array[0].rev_slope = 0.0;
	for ( n = 1 ; n < EMCMOT_COMP_SIZE+2 ; n++ ) {
	    joint->comp.array[n].nominal = DBL_MAX;
	    joint->comp.array[n].fwd_trim = 0.0;
	    joint->comp.array[n].rev_trim = 0.0;
	    joint->comp.array[n].fwd_slope = 0.0;
	    joint->comp.array[n].rev_slope = 0.0;
	}

	/* init status info */
	joint->flag = 0;
	joint->coarse_pos = 0.0;
	joint->pos_cmd = 0.0;
	joint->vel_cmd = 0.0;
	joint->backlash_corr = 0.0;
	joint->backlash_filt = 0.0;
	joint->backlash_vel = 0.0;
	joint->motor_pos_cmd = 0.0;
	joint->motor_pos_fb = 0.0;
	joint->pos_fb = 0.0;
	joint->ferror = 0.0;
	joint->ferror_limit = joint->min_ferror;
	joint->ferror_high_mark = 0.0;

	/* init internal info */
	cubicInit(&(joint->cubic));

	/* init misc other stuff in joint structure */
	joint->big_vel = 10.0 * joint->vel_limit;
	joint->home_state = 0;

	/* init joint flags (reduntant, since flag = 0 */

	SET_JOINT_ENABLE_FLAG(joint, 0);
	SET_JOINT_ACTIVE_FLAG(joint, 0);
	SET_JOINT_NHL_FLAG(joint, 0);
	SET_JOINT_PHL_FLAG(joint, 0);
	SET_JOINT_INPOS_FLAG(joint, 1);
	SET_JOINT_HOMING_FLAG(joint, 0);
	SET_JOINT_HOMED_FLAG(joint, 0);
	SET_JOINT_FERROR_FLAG(joint, 0);
	SET_JOINT_FAULT_FLAG(joint, 0);
	SET_JOINT_ERROR_FLAG(joint, 0);

    }

    /*! \todo FIXME-- add emcmotError */

    emcmotDebug->tMin = 0.0;
    emcmotDebug->tMax = 0.0;
    emcmotDebug->tAvg = 0.0;
    emcmotDebug->sMin = 0.0;
    emcmotDebug->sMax = 0.0;
    emcmotDebug->sAvg = 0.0;
    emcmotDebug->nMin = 0.0;
    emcmotDebug->nMax = 0.0;
    emcmotDebug->nAvg = 0.0;
    emcmotDebug->yMin = 0.0;
    emcmotDebug->yMax = 0.0;
    emcmotDebug->yAvg = 0.0;
    emcmotDebug->fyMin = 0.0;
    emcmotDebug->fyMax = 0.0;
    emcmotDebug->fyAvg = 0.0;
    emcmotDebug->fMin = 0.0;
    emcmotDebug->fMax = 0.0;
    emcmotDebug->fAvg = 0.0;

    emcmotDebug->cur_time = emcmotDebug->last_time = 0.0;
    emcmotDebug->start_time = etime();
    emcmotDebug->running_time = 0.0;

    /* init motion emcmotDebug->queue */
    if (-1 == tpCreate(&emcmotDebug->queue, DEFAULT_TC_QUEUE_SIZE,
	    emcmotDebug->queueTcSpace)) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    "MOTION: failed to create motion emcmotDebug->queue\n");
	return -1;
    }
//    tpInit(&emcmotDebug->queue); // tpInit called from tpCreate
    tpSetCycleTime(&emcmotDebug->queue, emcmotConfig->trajCycleTime);
    tpSetPos(&emcmotDebug->queue, emcmotStatus->carte_pos_cmd);
    tpSetVmax(&emcmotDebug->queue, emcmotStatus->vel, emcmotStatus->vel);
    tpSetAmax(&emcmotDebug->queue, emcmotStatus->acc);

    emcmotStatus->tail = 0;

    rtapi_print_msg(RTAPI_MSG_INFO, "MOTION: init_comm_buffers() complete\n");
    return 0;
}
Ejemplo n.º 8
0
LIBFLANG_ABI float libflang_etimef(float *time0, float *time1) {
  return etime(time0, time1);
}
Ejemplo n.º 9
0
LIBFLANG_ABI double libflang_etime(double *time0, double *time1) {
  return etime(time0, time1);
}
Ejemplo n.º 10
0
void print_etime()
{
    printf("etime = %f\n", etime());
}
Ejemplo n.º 11
0
// add photon background to the dose distribution
bool e_beam_triple_poly::add_photons(real &cpu_time, int n_batch)
{
   // measure CPU time
   real cpu_start = etime();

   // determine dose maximum
   float dose,dose_max = ZERO;
   for (register int k=0; k<dim.z; ++k)
   {
      for (register int j=0; j<dim.y; ++j)
      {
         for (register int i=0; i<dim.x; ++i)
         {
            dose = beam_dose->matrix[i][j][k];
            if (dose > dose_max) dose_max = dose;
         }
      }
   }
   xvmc_message("Maximum dose before photon correction:",
                 dose_max,"10^-10 Gy cm^2",1);

   // calculate scaled photon background depth parameters
   real p_a = photo_a*dose_max/100.0;
   real p_b = photo_b*dose_max/100.0;
   real p_c = 6.0*log(20.0)/energy_max;

   // calculate minimum and maximum beam angles for photon background
   real tan_x_min=(app_x1 - 10.0)/app_distance;
   real tan_x_max=(app_x2 + 10.0)/app_distance;
   real tan_y_min=(app_y1 - 10.0)/app_distance;
   real tan_y_max=(app_y2 + 10.0)/app_distance;

   // calculate photon background profile parameters
   real rx2 = 1.0 - (app_width_x-4.0)/42.0;
   rx2      = 0.66*(rx2*app_width_x)*(rx2*app_width_x);
   real ry2 = 1.0 - (app_width_y-4.0)/42.0;
   ry2      = 0.66*(ry2*app_width_y)*(ry2*app_width_y);

   // calculate photon background for all voxels
   // (fan lines from origin point to each voxel center)
   real_3 pos; // position of voxel center
   real_3 dop; // difference vector from origin to voxel center
   real   temp;

   pos.z = -voxel_size.z*ONE_HALF;
   for (register int k=0; k<dim.z; ++k)
   {
      pos.z +=  voxel_size.z;
      dop.z  =  pos.z - origin.z;

      pos.y  = -voxel_size.y*ONE_HALF;
      for (register int j=0; j<dim.y; ++j)
      {
         pos.y += voxel_size.y;
         dop.y  = pos.y - origin.y;

         pos.x  = -voxel_size.x*ONE_HALF;
         for (register int i=0; i<dim.x; ++i)
         {
            pos.x += voxel_size.x;
            dop.x  = pos.x - origin.x;

            // origin to voxel center distance
            real dist = sqrt(dop.x*dop.x + dop.y*dop.y + dop.z*dop.z);

            // fan line direction vector
            real_3 dir;
            dir.x = dop.x/dist;
            dir.y = dop.y/dist;
            dir.z = dop.z/dist;

            // rotate back by the table angle
            temp  = dir.x*sin_beta;
            dir.x = dir.x*cos_beta - dir.y*sin_beta;
            dir.y = temp           + dir.y*cos_beta;

            // rotate back by the gantry angle
            temp  = dir.x*sin_alpha;
            dir.x = dir.x*cos_alpha + dir.z*sin_alpha;
            dir.z = -temp           + dir.z*cos_alpha;

            // rotate back by the collimator angle
            temp  = dir.x*sin_gamma;
            dir.x = dir.x*cos_gamma - dir.y*sin_gamma;
            dir.y = temp            + dir.y*cos_gamma;

            // investigate fan lines
            if (fabs(dir.z) > ZERO)
            {
               real tan_x = dir.x/fabs(dir.z);
               real tan_y = dir.y/fabs(dir.z);

               // the fan line must be within the beam cone
               if ((tan_x > tan_x_min) && (tan_x < tan_x_max))
               {
                  if ((tan_y > tan_y_min) && (tan_y < tan_y_max))
                  {
                     // geometrical length within the cube (dummy variable)
                     real length = ZERO;

                     // effective length in water
                     real eff_length = trace_line(origin, pos, length);

                     // profile parameters
                     temp = app_distance*tan_x;
                     real bpx = exp(-temp*temp/rx2);
                     temp = app_distance*tan_y;
                     real bpy = exp(-temp*temp/ry2);

                     // depth parameters
                     real dose = p_b*(ONE-exp(-eff_length*p_c))
                               + p_a*eff_length;

                     // total photon dose (must be larger than 0)
                     dose *= bpx*bpy;
                     if (dose < ZERO) dose = ZERO;

                     // dose in vacuum or air is 0
                     real rho = density->matrix[i][j][k];
                     const real rho_min = 0.01;
                     dose = rho > rho_min ? dose : ZERO;

                     // the photon background should not contribute to the
                     // statistical uncertainty, the following update to the
                     // "beam_error->matrix" provides this functionality
                     real error =
                      (TWO*dose*beam_dose->matrix[i][j][k]+dose*dose)/n_batch;

                     // add photon background to beam dose and error matrices
                     beam_dose->matrix[i][j][k]  += dose;
                     beam_error->matrix[i][j][k] += error;
                  }
               }
            }
         }
      }
   }

   // measure CPU time
   cpu_time = etime() - cpu_start;

   return(true);
}