void
randread (struct randread_source *s, void *buf, size_t size)
{
  if (s->source)
    readsource (s, buf, size);
  else
    readisaac (&s->buf.isaac, buf, size);
}
static void
_dxf_READ_BUFFER (void *ctx, int llx, int lly, int urx, int ury, void *buff)
{
  ENTRY(("_dxf_READ_BUFFER (0x%x, %d, %d, %d, %d, 0x%x)",
	 ctx, llx, lly, urx, ury, buff));

  readsource(SRC_FRONT) ;
  lrectread (llx, lly, urx, ury, (unsigned long *)buff) ;

  EXIT((""));
}
static void
_dxf_captureZoomBox(tdmInteractor I, void *udata, float rot[4][4])
{
  register long *bp, *image ;
  register int i, iw, ih, n, y2 ;
  int x1, x2, y1 ;
  static long buff[4096] ;
  DEFDATA(I, tdmZoomData) ;

  readsource(SRC_FRONT);

  iw = CDATA(iw) ;
  ih = CDATA(ih) ;
  image = (long *)CDATA(image) ;

  /* clip coords to image to avoid invalid raster positions */
  x1 = (PDATA(x1)<0 ? 0 : (PDATA(x1)>(iw-1) ? iw-1 : PDATA(x1))) ;
  x2 = (PDATA(x2)<0 ? 0 : (PDATA(x2)>(iw-1) ? iw-1 : PDATA(x2))) ;
  y1 = (PDATA(y1)<0 ? 0 : (PDATA(y1)>(ih-1) ? ih-1 : PDATA(y1))) ;
  y2 = (PDATA(y2)<0 ? 0 : (PDATA(y2)>(ih-1) ? ih-1 : PDATA(y2))) ;

  lrectread (x1, y1, x2, y1, (const unsigned long *)image+(x1 + y1*iw)) ;
  if (y1 < (ih+1))
      lrectread (x1, y1+1, x2, y1+1,
			(const unsigned long *)image+(x1 + (y1+1)*iw)) ;

  lrectread (x1, y2, x2, y2, (const unsigned long *)image+(x1 + y2*iw)) ;
  if (y2 < (ih+1))
      lrectread (x1, y2+1, x2, y2+1, 
			(const unsigned long *)image+(x1 + (y2+1)*iw)) ;

  lrectread (x1, y1, x1, y2, (const unsigned long *)buff) ;
  for (bp=buff, n=x1+(y1*iw), i=y1 ; i<=y2 ; i++, n+=iw)
      image[n] = *bp++;
  if (x1 < iw-1)
  {
      lrectread (x1+1, y1, x1+1, y2, (const unsigned long *)buff) ;
      for (bp=buff, n=(x1+1)+(y1*iw), i=y1 ; i<=y2 ; i++, n+=iw)
	  image[n] = *bp++;
  }

  lrectread (x2, y1, x2, y2, (const unsigned long *)buff) ;
  for (bp=buff, n=x2+(y1*iw), i=y1 ; i<=y2 ; i++, n+=iw)
      image[n] = *bp++;

  if (x2 < iw-1)
  {
      lrectread (x2+1, y1, x2+1, y2, (const unsigned long *)buff) ;
      for (bp=buff, n=(x2+1)+(y1*iw), i=y1 ; i<=y2 ; i++, n+=iw)
	  image[n] = *bp++;
  }
}
Example #4
0
int fit() {
  
  cout << "start of fit procedure" << endl;

  readsource("run369/CRS/CRS_QDC_01!qdc01.dat",7214);
  readbackgr("run371/CRS/CRS_QDC_01!qdc01.dat",56948);
  corr();


  TCanvas* c1 = new TCanvas("c1","c1",800,600);



  int maxbin=-1;
  Double_t maxvalue=-1;
  Double_t tempbin=0;

  TString text="";

  hcorr->GetXaxis()->SetRange(200,4000);
  maxbin=hcorr->GetMaximumBin();
  maxvalue=hcorr->GetBinContent(maxbin);
  hcorr->GetXaxis()->SetRange(0,4095);

  TF1* f1 = new TF1("f1","[0]*exp(-((x-[1])^2)/[2])");
  f1->SetParameter(0,maxvalue);
  f1->SetParameter(1,maxbin);
  f1->SetParameter(2,1);

  f1->SetLineColor(2);

  hcorr->SetMinimum(0);
  hcorr->SetMaximum(1.2*maxvalue);

  hcorr->Fit("f1","","",maxbin-maxbin/6,4095);

  tempbin=sqrt(-log(maxvalue*2/3/(f1->GetParameter(0)))*(f1->GetParameter(2)))+f1->GetParameter(1);

  cout << "2/3 of maximum height is in bin " << tempbin << "->" <<int(tempbin+0.5) << endl;



  
  cout << endl << "max bin = " << maxbin << " with content = " << maxvalue << endl;



}
Example #5
0
int main(int argc, char **argv)
  {
  HFILE dHandle;
  char  *drive = "a:";
  int   choice;

  copyr();
  if ((argc > 2) || ((argc == 2) && (argv[1][1] != ':')))
    {
    fputs("usage: dskcpy2 drive_letter:", stderr);
    exit(1);
    }

  if (argc == 2)
    drive = argv[1];

  DosError(HARDERROR_DISABLE);
  do
    {
    choice = dskcpy_menu(gotSource, drive);
    switch (choice)
      {
      case READ_SOURCE:
        query("Place SOURCE disk in drive %s and strike any key when ready..", drive);
        if ((dHandle = opendrive(drive)) == 0) errorexit(dHandle);
        if (lockdrive(dHandle))                errorexit(dHandle);
        if (readsource(dHandle))               errorexit(dHandle);
        if (unlockdrive(dHandle))              errorexit(dHandle);
        DosClose(dHandle);
        break;
      case COPY_TARGET:
        query("Place TARGET disk in drive %s and strike any key when ready..", drive);
        if ((dHandle = opendrive(drive)) == 0) errorexit(dHandle);
        if (lockdrive(dHandle))                errorexit(dHandle);
        if (writetarget(dHandle))              errorexit(dHandle);
        if (unlockdrive(dHandle))              errorexit(dHandle);
        DosClose(dHandle);
        break;
      default:
        break;
      }
    }
  while (choice != EXIT_DSKCPY);

  return _DosError;
  }
int go_appendix_backgr(){

  readsource("run370/CRS/CRS_QDC_00!qdc00.dat",7215);
  readbackgr("run371/CRS/CRS_QDC_00!qdc00.dat",56948);
  corr();

  TPaveText *pt = new TPaveText(0.65,0.7,0.85,0.85, "NDC");
  pt->AddText("run371");
  pt->AddText("background");
  pt->AddText("box I (QDC ch00)");

  hbackgr->GetXaxis()->SetTitle("QDC energy [bin]");
  hbackgr->SetTitle("Background - box I");    
  TCanvas* c1=new TCanvas("c1","c1",800,300);
  hbackgr->Draw();
  pt->Draw("same");
  c1->SaveAs("appendix/backgr_boxI.jpg");


}
int go_appendix(){

  readsource("run370/CRS/CRS_QDC_00!qdc00.dat",7215);
  readbackgr("run371/CRS/CRS_QDC_00!qdc00.dat",56948);
  corr();

  TPaveText *pt = new TPaveText(0.65,0.7,0.85,0.85, "NDC");
  pt->AddText("run371");
  pt->AddText("Cs-137");
  pt->AddText("box I (QDC ch00)");
  pt->AddText("compton edge in bin 860 +- 20");

  hcorr->GetXaxis()->SetTitle("QDC energy [bin]");
  hcorr->SetTitle("Cs-137 - box I");    
  TCanvas* c1=new TCanvas("c1","c1",800,300);
  hcorr->Draw();
  pt->Draw("same");
  c1->SaveAs("appendix/Cs-137_boxI.jpg");


}
Example #8
0
int fit251() {

  readsource("run251/TDC/quadA_2.dat",255128);

  pt251->AddText("run251 - source inside nero (holder)");
  pt251->AddText("one paddle covers end of beamline hole");
  pt251->AddText("using only bottom paddle for stop");

  maxbin=hsource->GetMaximumBin();

  gPad->SetLogy(0); 
  gPad->Modified();  

  TString formula1="[0]+[1]*exp(x/[2])";

  TF1* f1 = new TF1("f1",formula1);
  f1->SetParameter(0,05);
  f1->SetParameter(1,05);
  f1->SetParameter(2,maxbin/2);
  f1->SetLineColor(2);

  hsource->Fit("f1","","",1500,maxbin);
  f1->GetParameter(0);


  TString formula2="[0]+[1]*x";

  TF1* f2 = new TF1("f2",formula2);
  f2->SetParameter(0,05);
  f2->SetParameter(1,05);
  f2->SetLineColor(2);

  hsource->Fit("f2","","",1995,2020);


  TF1* f3 = new TF1("f3","[0]",0,3000);
  f3->SetParameter(0,offset);
  f3->SetLineColor(3);
  f3->Draw("same");

  double linearbackgr = f1->GetParameter(0);

  tempbin= (f1->GetParameter(0) - f2->GetParameter(0)) /  f2->GetParameter(1);


  cout << "bin number of edge (by lin fit) = " << tempbin << endl;

 
  //  all_n = f1->Integral(0,int(tempbin+0.5)) - f1->GetParameter(0)*int(tempbin);

  //  cout << "number of all det. neutrons = " << all_n << endl;


  




  pt251->Draw();

  //  int startbin=2000;

  cout << "end of fit procedure" <<endl;

}
Example #9
0
int fit() {
  
  cout << "start of fit procedure" << endl;

  //  readsource("run374/CRS/CRS_QDC_01!qdc01.dat",64343);
  readbackgr("run377/CRS/CRS_QDC_01!qdc01.dat",251);
  readsource("run377/CRS/CRS_QDC_00!qdc00.dat",251);
  corr();

  TPaveText *pt = new TPaveText(0.65,0.7,0.85,0.85, "NDC");
  pt->AddText("run374-run371");
  pt->AddText("Co60");
  pt->AddText("ch01 - box II");

  /*
  int maxbin=-1;
  Double_t maxvalue=-1;
  Double_t tempbin=0;
  Double_t tempbinerror=0;

  TString text="";

  hcorr->GetXaxis()->SetRange(200,4000);
  maxbin=hcorr->GetMaximumBin();
  maxvalue=hcorr->GetBinContent(maxbin);
  hcorr->GetXaxis()->SetRange(0,4095);

  TF1* f1 = new TF1("f1","[0]*exp(-((x-[1])^2)/[2])");
  f1->SetParameter(0,maxvalue);
  f1->SetParameter(1,maxbin);
  f1->SetParameter(2,500);

  f1->SetLineColor(2);

  hcorr->SetMinimum(0);
  hcorr->SetMaximum(1.2*maxvalue);

  hcorr->Fit("f1","","",900,4095);
  //  hcorr->Fit("f1","","",maxbin-maxbin/6,4095);

  pt->Draw();


  tempbin=sqrt(-log(maxvalue*2/3/(f1->GetParameter(0)))*(f1->GetParameter(2)))+f1->GetParameter(1);

  c1->SaveAs("PDF/energycal/run374-Co60-boxII.pdf");


  tempbinerror=sqrt( (1/(2*sqrt(-log(maxvalue*2/3/(f1->GetParameter(0)))*(f1->GetParameter(2)))+f1->GetParameter(1)) * f1->GetParError(0)/f1->GetParameter(0))**2 +

   ( 1/(2*sqrt(-log(maxvalue*2/3/(f1->GetParameter(0)))*(f1->GetParameter(2)))+f1->GetParameter(1)) *(-log(maxvalue*2/3/(f1->GetParameter(2))))*f1->GetParError(2))**2   +  

   ( 1/(2*sqrt(-log(maxvalue*2/3/(f1->GetParameter(0)))*(f1->GetParameter(2)))+f1->GetParameter(1))*f1->GetParError(1))**2              );







  cout << "2/3 of maximum height is in      tempbin = " << tempbin << "->" <<int(tempbin+0.5) << endl;
  cout << "                            tempbinerror = " << tempbinerror << endl;

  
  cout << endl << "max bin = " << maxbin << " with content = " << maxvalue << endl;

  */

}
Example #10
0
/******************************************************** Main Function **************************************************/
int main (int argc, char **argv)
{
	//inputs
	FILE *f_src; //source file pointer
	FILE *f_src_ctr; //source center file
	//outputs
	FILE *f_cid; //cluster-id file pointer
	FILE *f_mfi; //added April 16, 2009
	

	char name_string[LINE_LEN]; //for name use

	int time_id=-1;

	long file_Len=0;
	long num_clust=0;
	long num_dm=0;
	long norm_used=0;
	long dist_used=0;
	long i=0;
	long j=0;

	long *cluster_id;
	long *IDmapping; //this is to keep the original populationID of the center.txt

	double kmean_term=0;
	
	double **cluster_center;
	double **orig_data;
	double **normalized_data;
		
/*
	_strtime( tmpbuf );
    printf( "Starting time:\t\t\t\t%s\n", tmpbuf );
	_strdate( tmpbuf );
    printf( "Starting date:\t\t\t\t%s\n", tmpbuf );
*/

	if (argc!=3)
	{
		//modified on July 23, 2010
		fprintf(stderr, "usage: cent_adjust input_center input_data_file\n");       
		abort();
	}	
	

	f_src_ctr=fopen(argv[1],"r");	
	
	//read source data
	f_src=fopen(argv[2],"r");
	
	getfileinfo(f_src, &file_Len, &num_dm, name_string, &time_id); //get the filelength, number of dimensions, and num/name of parameters

	rewind(f_src); //reset data file pointer	

	orig_data = (double **)malloc(sizeof(double*)*file_Len);
	memset(orig_data,0,sizeof(double*)*file_Len);
	for (i=0;i<file_Len;i++)
	{
		orig_data[i]=(double *)malloc(sizeof(double)*num_dm);
		memset(orig_data[i],0,sizeof(double)*num_dm);
	}
	
	readsource(f_src, file_Len, num_dm, orig_data, time_id); //read the data;
	
	fclose(f_src);
	/////////////////////////////////////////////////////////////////////////////
	getctrfileinfo(f_src_ctr, &num_clust); //get how many populations
	norm_used=0;
	dist_used=0;
	kmean_term=3;  //modified on Oct 16, 2009: changed kmean_term=1 to kmean_term=2

	rewind(f_src_ctr); //reset center file pointer

	//read population center
	cluster_center=(double **)malloc(sizeof(double*)*num_clust);
	memset(cluster_center,0,sizeof(double*)*num_clust);
	for (i=0;i<num_clust;i++)
	{
		cluster_center[i]=(double*)malloc(sizeof(double)*num_dm);
		memset(cluster_center[i],0,sizeof(double)*num_dm);
	}
	for (i=0;i<num_clust;i++)
		for (j=0;j<num_dm;j++)
			cluster_center[i][j]=0;

	IDmapping=(long *)malloc(sizeof(long)*num_clust);
	memset(IDmapping,0,sizeof(long)*num_clust);

	readcenter(f_src_ctr,num_clust,num_dm,cluster_center,IDmapping); //read population center
    fclose(f_src_ctr);

	/////////////////////////////////////////////////////////////////////////////
	normalized_data=(double **)malloc(sizeof(double*)*file_Len);
	memset(normalized_data,0,sizeof(double*)*file_Len);
	for (i=0;i<file_Len;i++)
	{
		normalized_data[i]=(double *)malloc(sizeof(double)*num_dm);
		memset(normalized_data[i],0,sizeof(double)*num_dm);
	}
	
	tran(orig_data, file_Len, num_dm, norm_used, normalized_data);
	/************************************************* Compute number of clusters *************************************************/
	
	cluster_id=(long*)malloc(sizeof(long)*file_Len);
	memset(cluster_id,0,sizeof(long)*file_Len);

	assign_event(normalized_data,num_clust,dist_used,kmean_term,file_Len,num_dm,cluster_id,cluster_center,0);

	
	//show(orig_data,cluster_id,file_Len,num_clust,num_dm,show_data,num_disp,name_string); 
	show(orig_data, cluster_id, file_Len, num_clust, num_dm, name_string, IDmapping);

	f_cid=fopen("population_id.txt","w");

	for (i=0;i<file_Len;i++)
		fprintf(f_cid,"%d\n",IDmapping[cluster_id[i]]);
		

	fclose(f_cid);
 
	//added April 16, 2009
	f_mfi=fopen("MFI.txt","w");

	for (i=0;i<num_clust;i++)
	{
		fprintf(f_mfi,"%d\t",IDmapping[i]);

		for (j=0;j<num_dm;j++)
		{
			if (j==num_dm-1)
				fprintf(f_mfi,"%.0f\n",cluster_center[i][j]);
			else
				fprintf(f_mfi,"%.0f\t",cluster_center[i][j]);
		}
	}
	fclose(f_mfi);

	//ended April 16, 2009

	for (i=0;i<num_clust;i++)
		free(cluster_center[i]);
	free(cluster_center);
		

	/********************************************** Release memory ******************************************/
  
	for (i=0;i<file_Len;i++)
	{
		free(orig_data[i]);		
		free(normalized_data[i]);
	}
	
	free(orig_data);
	free(normalized_data);
	free(cluster_id);
	free(IDmapping);

/*
	_strtime( tmpbuf );
    printf( "Ending time:\t\t\t\t%s\n", tmpbuf );
	_strdate( tmpbuf );
    printf( "Ending date:\t\t\t\t%s\n", tmpbuf );
*/

}
static void 
_dxf_DRAW_GNOMON (tdmInteractor I, void *udata, float rot[4][4], int draw)
{
  /*
   *  draw == 1 to draw gnomon, draw == 0 to undraw.  This is done with
   *  two separate calls in order to support explicit erasure of edges for
   *  some implementations.  A draw is always preceded by an undraw and
   *  the pair of invocations is atomic.
   *
   *  Computations are done in normalized screen coordinates in order to
   *  render arrow heads correctly.
   */

  DEFDATA(I,tdmRotateData) ;
  DEFPORT(I_PORT_HANDLE) ;
  int dummy = 0 ;
  float origin[2] ;
  float xaxis[2],  yaxis[2],  zaxis[2] ;
  float xlabel[2], ylabel[2], zlabel[2] ;

  ENTRY(("_dxf_DRAW_GNOMON (0x%x, 0x%x, 0x%x, %d)",I, udata, rot, draw));

  if (PDATA(font) == -1)
    {
      /* font width for axes labels in normalized coordinates */
      font(0) ;
      PDATA(font) = 0 ;
      PDATA(swidth) = (float)strwidth("Z")/(float)GNOMONRADIUS ;

      /* 1 pixel in normalized coordinates */
      PDATA(nudge) = 1.0/(float)GNOMONRADIUS ;
    }
  else
      font(PDATA(font)) ;
  
  if (draw)
    {
      lmcolor(LMC_COLOR) ;
      cpack(0xffffffff) ;
      linewidth(1) ;
    }
  else
    {
      if (PDATA(redrawmode) != tdmViewEchoMode)
	{
	  /*
	   *  In tdmViewEchoMode (DX's Execute On Change), we are drawing
	   *  the gnomon echo on top of a background image that is redrawn
	   *  with every frame of a direct interaction.
	   *
	   *  If we're not in that mode, the background image is static
	   *  while the gnomon echo rotates in front of it, so erasing the
	   *  gnomon means we have to repair damage to the background.  We
	   *  do this by blitting a portion of the static image to the
	   *  back buffer, drawing the gnomon over that, then blitting the
	   *  combined results back to the front buffer.
	   */
	  
	  /* force graphics output into back buffer */
	  frontbuffer(FALSE) ;
	  backbuffer(TRUE) ;
	  
	  /* erase gnomon background */
	  lrectwrite (PDATA(illx), PDATA(illy),
		      PDATA(iurx), PDATA(iury), PDATA(background)) ;
	}

#ifndef NOSHADOW      
      /* draw wide black lines to ensure visibility against background */
      lmcolor(LMC_COLOR) ;
      cpack(0x0) ;
      linewidth(2) ;
#else
      EXIT(("No shadow"));
      return ;
#endif
    }

  origin[0] = 0 ;
  origin[1] = 0 ;

  xaxis[0] = 0.7 * rot[0][0] ; xaxis[1] = 0.7 * rot[0][1] ;
  yaxis[0] = 0.7 * rot[1][0] ; yaxis[1] = 0.7 * rot[1][1] ;
  zaxis[0] = 0.7 * rot[2][0] ; zaxis[1] = 0.7 * rot[2][1] ;

  xlabel[0] = 0.8 * rot[0][0] ; xlabel[1] = 0.8 * rot[0][1] ;
  ylabel[0] = 0.8 * rot[1][0] ; ylabel[1] = 0.8 * rot[1][1] ;
  zlabel[0] = 0.8 * rot[2][0] ; zlabel[1] = 0.8 * rot[2][1] ;

  pushmatrix() ;
  loadmatrix(identity) ;
  bgnline() ; v2f(origin) ; v2f(xaxis) ; endline() ;
  _dxf_DRAW_ARROWHEAD(PORT_CTX, xaxis[0], xaxis[1]) ;

  bgnline() ; v2f(origin) ; v2f(yaxis) ; endline() ;
  _dxf_DRAW_ARROWHEAD(PORT_CTX, yaxis[0], yaxis[1]) ;

  bgnline() ; v2f(origin) ; v2f(zaxis) ; endline() ;
  _dxf_DRAW_ARROWHEAD(PORT_CTX, zaxis[0], zaxis[1]) ;
  
  if (xlabel[0] <= 0) xlabel[0] -= PDATA(swidth) ;
  if (xlabel[1] <= 0) xlabel[1] -= PDATA(swidth) ;
  
  if (ylabel[0] <= 0) ylabel[0] -= PDATA(swidth) ;
  if (ylabel[1] <= 0) ylabel[1] -= PDATA(swidth) ;
  
  if (zlabel[0] <= 0) zlabel[0] -= PDATA(swidth) ;
  if (zlabel[1] <= 0) zlabel[1] -= PDATA(swidth) ;

#ifndef NOSHADOW  
  if (!draw)
    {
      /* offset text slightly for shadow */
      xlabel[0] += PDATA(nudge) ; xlabel[1] -= PDATA(nudge) ;
      ylabel[0] += PDATA(nudge) ; ylabel[1] -= PDATA(nudge) ;
      zlabel[0] += PDATA(nudge) ; zlabel[1] -= PDATA(nudge) ;
    }
#endif

  font(0) ;
  cmov2 (xlabel[0], xlabel[1]) ;
  charstr ("X") ;
  cmov2 (ylabel[0], ylabel[1]) ;
  charstr ("Y") ;
  cmov2 (zlabel[0], zlabel[1]) ;
  charstr ("Z") ;

  popmatrix() ;

  if (draw && PDATA(redrawmode) != tdmViewEchoMode)
    {
      /* copy rendered gnomon from back buffer to front buffer */
      readsource(SRC_BACK) ;
      frontbuffer(TRUE) ;
      backbuffer(FALSE) ;
      rectcopy (PDATA(illx), PDATA(illy), PDATA(iurx), PDATA(iury),
		PDATA(illx), PDATA(illy)) ;

      /* restore original buffer config from current tdmFrontBufferDraw */
      _dxf_BUFFER_RESTORE_CONFIG
	  (PORT_CTX, dummy, PDATA(buffermode), tdmFrontBufferDraw) ;
    }

  EXIT((""));
} 
static void 
_dxf_DRAW_GLOBE (tdmInteractor I, void *udata, float rot[4][4], int draw)
{
  /*
   *  draw == 1 to draw globe, draw == 0 to undraw.  This is done with two
   *  separate calls in order to support explicit erasure of edges for
   *  some implementations.  A draw is always preceded by an undraw and
   *  the pair of invocations is atomic.
   */

  DEFDATA(I,tdmRotateData) ;
  DEFPORT(I_PORT_HANDLE) ;
  int u, v, on, dummy = 0 ;

  /* globe edge visibility flags.  all globe instance share this data. */
  static struct {
    int latvis, longvis ;
  } edges[LATS][LONGS] ;

  /* globe and globeface defined in tdmGlobeEchoDef.h */
  register const float (*Globe)[LONGS][3] = globe ;
  register const struct Face (*Globeface)[LONGS] = globeface ;

  /* view normal */
  register float z0, z1, z2 ;
  z0 = rot[0][2] ; z1 = rot[1][2] ; z2 = rot[2][2] ;

#define FACEVISIBLE(u,v,z0,z1,z2) \
  (Globeface[u][v].norm[0] * z0 + \
   Globeface[u][v].norm[1] * z1 + \
   Globeface[u][v].norm[2] * z2 > 0.0)

  ENTRY(("_dxf_DRAW_GLOBE (0x%x, 0x%x, 0x%x, %d)",I, udata, rot, draw));

  if (draw)
    {
      lmcolor(LMC_COLOR) ;
      cpack(0xffffffff) ;
      linewidth(1) ;
    }
  else
    {
      if (PDATA(redrawmode) != tdmViewEchoMode)
	{
	  /*
	   *  In tdmViewEchoMode (DX's Execute On Change), we are drawing
	   *  the globe echo on top of a background image that is redrawn
	   *  with every frame of a direct interaction.
	   *
	   *  If we're not in that mode, the background image is static
	   *  while the globe echo rotates in front of it, so erasing the
	   *  globe means we have to repair damage to the background.  We
	   *  do this by blitting a portion of the static image to the
	   *  back buffer, drawing the globe over that, then blitting the
	   *  combined results back to the front buffer.
	   */
	  
	  /* force graphics output into back (draw) buffer */
	  frontbuffer(FALSE) ;
	  backbuffer(TRUE) ;
	  
	  /* erase globe background */
	  lrectwrite (PDATA(illx), PDATA(illy),
		      PDATA(iurx), PDATA(iury), PDATA(background)) ;
	}

#ifndef NOSHADOW      
      /* draw wide black lines to ensure visibility against background */
      lmcolor(LMC_COLOR) ;
      cpack(0x0) ;
      linewidth(2) ;
#else
      EXIT(("No shadow"));
      return ;
#endif
    }

#ifndef FACEVIS
  /*
   *  Compute visible edges explicitly.  This method might be faster and
   *  works in XOR mode but as implemented here is applicable only for a
   *  globe-type object rendered with latitude and longitude lines.
   */
#ifndef NOSHADOW
  if (!draw)
#endif
      for (u=0 ; u<LATS-1 ; u++)
	{
	  if (FACEVISIBLE(u, 0, z0, z1, z2))
	    {
	      edges[u][LONGS-1].latvis++ ;
	      edges[u+1][LONGS-1].latvis++ ;
	      edges[u][0].longvis++ ;
	      edges[u][LONGS-1].longvis++ ;
	    }
	  for (v=1 ; v<LONGS ; v++)
	      if (FACEVISIBLE(u, v, z0, z1, z2))
		{
		  edges[u][v-1].latvis++ ;
		  edges[u+1][v-1].latvis++ ;
		  edges[u][v].longvis++ ;
		  edges[u][v-1].longvis++ ;
		}
	}

  /* north pole */
  if (z1 > 0.0)
      for (v=0 ; v<LONGS ; v++)
	  edges[LATS-1][v].latvis++ ;

  /* south pole */
  if (z1 < 0.0)
      for (v=0 ; v<LONGS ; v++)
	  edges[0][v].latvis++ ;

  /*
   *  Draw each visible edge exactly once.
   */
  for (u=0 ; u<LATS ; u++)
    {
      for (v=0, on=0 ; v<LONGS-1 ; v++)
	  if (edges[u][v].latvis)
	    {
	      if (!on)
		{
		  on = 1 ;
		  bgnline() ;
		  v3f(Globe[u][v]) ;
		}
	      v3f (Globe[u][v+1]) ;
#ifndef NOSHADOW
	      if (draw)
#endif
		  edges[u][v].latvis = 0 ;
	    }
	  else if (on)
	    {
	      on = 0 ;
	      endline() ;
	    }

      /* close latitude line if necessary */
      if (edges[u][LONGS-1].latvis)
	{
	  if (!on)
	    {
	      bgnline() ;
	      v3f(Globe[u][LONGS-1]) ;
	    }
	  v3f (Globe[u][0]) ;
	  endline() ;
#ifndef NOSHADOW
	  if (draw)
#endif
	      edges[u][LONGS-1].latvis = 0 ;
	}
      else if (on)
	  endline() ;
    }
      
  /* longitude lines */
  for (v=0 ; v<LONGS ; v++)
    {
      for (u=0, on=0 ; u<LATS-1 ; u++)
	  if (edges[u][v].longvis)
	    {
	      if (!on)
		{
		  on = 1 ;
		  bgnline() ;
		  v3f(Globe[u][v]) ;
		}
	      v3f(Globe[u+1][v]) ;
#ifndef NOSHADOW
	      if (draw)
#endif
		  edges[u][v].longvis = 0 ;
	    }
	  else if (on)
	    {
	      on = 0 ;
	      endline() ;
	    }
      if (on)
	  endline() ;
    }
#else  
  /*
   *  Do it the easy way:  draw all visible faces regardless of shared
   *  edges.  Most edges are drawn twice, so this is slower and not
   *  compatible with XOR rendering.
   */
  for (u=0 ; u<LATS-1 ; u++)
      for (v=0 ; v<LONGS ; v++)
	  if (FACEVISIBLE(u, v, z0, z1, z2))
	      poly (4, Globeface[u][v].face) ;

  /* north pole */
  if (z1 > 0.0)
      poly (LONGS, Globe[LATS-1]) ;

  /* south pole */
  if (z1 < 0.0)
      poly (LONGS, Globe[0]) ;

#endif /* ifndef FACEVIS */

  if (draw && PDATA(redrawmode) != tdmViewEchoMode)
    {
      /* copy rendered globe from back buffer to front buffer */
      readsource(SRC_BACK) ;
      frontbuffer(TRUE) ;
      backbuffer(FALSE) ;
      rectcopy (PDATA(illx), PDATA(illy), PDATA(iurx), PDATA(iury),
		PDATA(illx), PDATA(illy)) ;

      /* restore original buffer config from current tdmFrontBufferDraw */
      _dxf_BUFFER_RESTORE_CONFIG
	  (PORT_CTX, dummy, PDATA(buffermode), tdmFrontBufferDraw) ;
    }
  EXIT((""));
}