Example #1
0
int main() {
    // Don't associate histograms with TFiles so we can delete them
    TH1::AddDirectory(false);

    // Set our style
    set_plot_style();

    // Get the histograms
    const std::string INPUT_FILE =
        "/data/whybee0a/user/gude_2/IDPlots/20150416/2012_ALL_hadded.root";
    const std::string INPUT_MC_FILE =
        "/data/whybee0a/user/gude_2/IDPlots/20150416/MadGraph_hadded.root";

    // Load the histograms
    // Data
    std::unique_ptr<TH1D> h_r9 = get_histogram(INPUT_FILE, "IDPlotter/r9");
    std::unique_ptr<TH1D> h_sigma_ieta_ieta_eb = get_histogram(INPUT_FILE, "IDPlotter/sieie_eb");
    std::unique_ptr<TH1D> h_sigma_ieta_ieta_ee = get_histogram(INPUT_FILE, "IDPlotter/sieie_ee");
    std::unique_ptr<TH1D> h_he = get_histogram(INPUT_FILE, "IDPlotter/he");
    std::unique_ptr<TH1D> h_deta = get_histogram(INPUT_FILE, "IDPlotter/deta");
    std::unique_ptr<TH1D> h_dphi = get_histogram(INPUT_FILE, "IDPlotter/dphi");
    std::unique_ptr<TH1D> h_track_iso = get_histogram(INPUT_FILE, "IDPlotter/track_iso");
    std::unique_ptr<TH1D> h_ecal_iso = get_histogram(INPUT_FILE, "IDPlotter/ecal_iso");
    std::unique_ptr<TH1D> h_hcal_iso = get_histogram(INPUT_FILE, "IDPlotter/hcal_iso");
    std::unique_ptr<TH1D> h_1oe_1op = get_histogram(INPUT_FILE, "IDPlotter/1oe_1op");
    std::unique_ptr<TH1D> h_d0 = get_histogram(INPUT_FILE, "IDPlotter/d0");
    std::unique_ptr<TH1D> h_dz = get_histogram(INPUT_FILE, "IDPlotter/dz");
    std::unique_ptr<TH1D> h_mhits = get_histogram(INPUT_FILE, "IDPlotter/mhits");
    std::unique_ptr<TH1D> h_iso = get_histogram(INPUT_FILE, "IDPlotter/iso");
    std::unique_ptr<TH1D> h_nmiss = get_histogram(INPUT_FILE, "IDPlotter/mhits");
    // MC
    std::unique_ptr<TH1D> h_r9_mc = get_histogram(INPUT_MC_FILE, "IDPlotter/r9");
    std::unique_ptr<TH1D> h_sigma_ieta_ieta_eb_mc = get_histogram(INPUT_MC_FILE, "IDPlotter/sieie_eb");
    std::unique_ptr<TH1D> h_sigma_ieta_ieta_ee_mc = get_histogram(INPUT_MC_FILE, "IDPlotter/sieie_ee");
    std::unique_ptr<TH1D> h_he_mc = get_histogram(INPUT_MC_FILE, "IDPlotter/he");
    std::unique_ptr<TH1D> h_deta_mc = get_histogram(INPUT_MC_FILE, "IDPlotter/deta");
    std::unique_ptr<TH1D> h_dphi_mc = get_histogram(INPUT_MC_FILE, "IDPlotter/dphi");
    std::unique_ptr<TH1D> h_track_iso_mc = get_histogram(INPUT_MC_FILE, "IDPlotter/track_iso");
    std::unique_ptr<TH1D> h_ecal_iso_mc = get_histogram(INPUT_MC_FILE, "IDPlotter/ecal_iso");
    std::unique_ptr<TH1D> h_hcal_iso_mc = get_histogram(INPUT_MC_FILE, "IDPlotter/hcal_iso");
    std::unique_ptr<TH1D> h_1oe_1op_mc = get_histogram(INPUT_MC_FILE, "IDPlotter/1oe_1op");
    std::unique_ptr<TH1D> h_d0_mc = get_histogram(INPUT_MC_FILE, "IDPlotter/d0");
    std::unique_ptr<TH1D> h_dz_mc = get_histogram(INPUT_MC_FILE, "IDPlotter/dz");
    std::unique_ptr<TH1D> h_mhits_mc = get_histogram(INPUT_MC_FILE, "IDPlotter/mhits");
    std::unique_ptr<TH1D> h_iso_mc = get_histogram(INPUT_MC_FILE, "IDPlotter/iso");
    std::unique_ptr<TH1D> h_nmiss_mc = get_histogram(INPUT_MC_FILE, "IDPlotter/mhits");

    // Write pdfs
    const std::string NO_CHANGE = "";
    const double NO_LINE = -100;
    write_plot(h_r9, h_r9_mc, "r9.pdf", 50, "R9", NO_LINE, 0.94, 0, 1);
    write_plot(h_sigma_ieta_ieta_eb, h_sigma_ieta_ieta_eb_mc, "sigma_ieta_ieta_eb.pdf", 20, "#sigma_{i #eta i #eta} in EB", NO_LINE, 0.01, 0, 0.03);
    write_plot(h_sigma_ieta_ieta_ee, h_sigma_ieta_ieta_ee_mc, "sigma_ieta_ieta_ee.pdf", 50, "#sigma_{i #eta i #eta} in EB", NO_LINE, 0.03, 0, 0.09);
    write_plot(h_he, h_he_mc, "he.pdf", 10, "H / E", NO_LINE, 0.12, 0, 0.14);
    write_plot(h_deta, h_deta_mc, "deta.pdf", 20, NO_CHANGE, 0.007, 0.005, -0.018, 0.018);
    write_plot(h_dphi, h_dphi_mc, "dphi.pdf", 20, NO_CHANGE, 0.06, 0.03, -0.14, 0.14);
    //write_plot(h_track_iso, h_track_iso_mc, "track_iso.pdf", 200);
    write_plot(h_ecal_iso, h_ecal_iso_mc, "ecal_iso.pdf", 50, NO_CHANGE, NO_LINE, 0.15, 0, 1);
    write_plot(h_hcal_iso, h_hcal_iso_mc, "hcal_iso.pdf", 50, NO_CHANGE, NO_LINE, 0.1, 0, 0.2);
    write_plot(h_1oe_1op, h_1oe_1op_mc, "1oe_1op.pdf", 50, NO_CHANGE, NO_LINE, 0.05, -0.15, 0.15);
    write_plot(h_d0, h_d0_mc, "d0.pdf", 400, NO_CHANGE, NO_LINE, 0.02, -0.06, 0.06);
    write_plot(h_dz, h_dz_mc, "dz.pdf", 20, NO_CHANGE, NO_LINE, 0.1, -0.3, 0.3);
    write_plot(h_iso, h_iso_mc, "iso.pdf", 100, NO_CHANGE, 0.15, 0.10, 0, 0.5);
    write_plot(h_nmiss, h_nmiss_mc, "nmiss.pdf", 1, NO_CHANGE, 2, 1, 0, 3);

    return EXIT_SUCCESS;
}
Example #2
0
int main(int argc, char *argv[]) 
{
    char buff[BUFLEN], sysbuff[2*BUFLEN];         
    short * ptr;                                  
    int i;                                        
    int testMode;                                 // Test mode (RTT/througput)
    int lossPackets;                              // Lost packet number
    long_int * s_rtime_usec;                      // Server process wall clock time 
    long_int * s_utime_usec;                      // Server process time in user mode
    long_int * s_stime_usec;                      // Server process time in system mode
    double clientTP, serverTP;                    // client/server throughputs
    double lossRate;                              // Packet loss rate
    struct SYSInfo * sysinfo = NULL;              // System (CPU/Interrupts) information
    struct SYSInfo * serverinfo = NULL;           // Server's system information
    struct PROInfo * proinfo;                     // Process information
    struct timeval tv;                            // Timestamp
    double ts;

    /**************** At least given server name ***************************/

    if ( argc > 1 && strcmp(argv[1], "--help")==0 ) {
	fprintf(stderr, help_description);
	fprintf(stderr, help_usage,  DEFAULTPORT, DEFAULTDATAGRAM, DEFAULTSIZE, 
		DEFAULTPORT, DEFAULTREPEAT, DEFAULTTIME);
	fprintf(stderr, help_example);
	return 0;
    } else if ( argc < 3 ) {
	print_usage();
	return 1;
    }

    /********* Data initialization and parse the command line **************/
    
    init_data();
    parse_command(argc, argv, &testMode);

    /********* Just send data in case of UDP traffic generator *************/
    
    if ( setting.udpGen ) {
	udp_traffic_generator(hostname, tcpsock.port, udpsock.sendBuf,
			      setting.testTime, setting.throughput);
	return 0;
    }

    /******************** Check the write file option **********************/

    if ( setting.writeOption ) {
	if ( (output = fopen(filename, "w")) == NULL ) {
	    fprintf(stderr, "%s: Unable to write the file!\n", filename);
	    setting.writeOption = 0;
	}
    } 

    /*************** Allocate memory to hold CPU information ***************/
    
    if ( setting.CPUoption ) { 

	/** Two more items to hold the syslog of pre/post states of test ***/

	if ( (sysinfo = (struct SYSInfo *)malloc((setting.repeat + 2) 
			* sizeof(struct SYSInfo))) == NULL ) {
	    perror("Failed to malloc.");
	    exit(1);
	}

	if ( start_trace_system( &sysinfo[0]) == NOTOK ) {
	    fprintf(stderr, "Failed to monitor system information.\n");
	    setting.CPUoption = 0;
	} else {
	    sleep(1);
	    stop_trace_system( &sysinfo[0] );
	}
    }
 
    /***********************  TCP connection to server *********************/

    if (client_tcp_connect(hostname, &tcpsock) == NOTOK) {
	fprintf(stderr, "%s : %d ", hostname, tcpsock.port);
	perror("Unable to establish TCP connection.");
	return 1;
    }

    /*************** Send parameters to server *****************************/
    
    sprintf(buff, test_init_str, testMode, udpsock.tos, setting.CPUoption, 
	    server.sendBuf, server.recvBuf, udpsock.packetSize, udpsock.dataSize);
    if ( tcp_send_request(buff, strlen(buff), &tcpsock) == NOTOK ) {
	perror("TCP send parameters error.");
	return 1;
    }
 
    /************  Get server's UDP connection setting *********************/

    if ( tcp_get_request(buff, &tcpsock) == NOTOK || 
	 sscanf(buff, server_setting_str, &udpsock.port, &server.tos, 
		&setting.sCPUoption, &server.sendBuf, &server.recvBuf, 
		&server.packetSize, &server.dataSize) != 7) {
	perror("Failed to get UDP connection information.");
	return 1;
    }    

    /************ Initialization of UDP communication  *********************/

    if (client_udp_init(hostname, &udpsock) == NOTOK) {
	fprintf(stderr, "%s : %d ", hostname, udpsock.port);
	perror("Failed to establish the UDP connection.");
	return 1;
    }

    if ( gethostname(localhost, BUFLEN) < 0 ) {
	perror("gethostname.");
	strcpy(localhost, "Localhost");
    }

    /************************* Allocate memory *****************************/

    if ( (buffer = (char *) malloc ( udpsock.packetSize)) == NULL ){
	fprintf(stderr, "Malloc error : %d\n", udpsock.packetSize);
        return 1;
    }

    /******* Randomize the buffer to prevent the possible compression ******/
    
    srand(time(NULL));
    for(ptr = (short *)buffer; ptr < (short *)(buffer+udpsock.packetSize); ptr += 2 )
	*ptr = (short)rand();

    /*** Allocate memory to store the client/server process information ****/
	
    if ( (proinfo = (struct PROInfo *)malloc((setting.repeat)*sizeof(struct PROInfo))) == NULL ||
	 (s_rtime_usec = (long_int *)malloc((setting.repeat)*sizeof(long_int))) == NULL ||
	 (s_utime_usec = (long_int *)malloc((setting.repeat)*sizeof(long_int))) == NULL ||
	 (s_stime_usec = (long_int *)malloc((setting.repeat)*sizeof(long_int))) == NULL ) {
	perror("Failed to malloc.");
	exit(1);
    }
    
#ifdef DEBUG
    fprintf(stderr, " DEBUG: Client connected to server on port: %d\n", udpsock.port);
#endif

    /********************** Handle the interruption ************************/

    signal(SIGINT, sig_handler);
    signal(SIGTSTP, sig_handler);

    /********************** RTT (latency test) *****************************/

    if ( testMode == LATENCY ) {
	udp_ping();
	print_ping_result();
	return 0;
    }

    /************************ UDP throughput test **************************/

    /** We need another container to hold server's system info if defined **/

    if ( setting.sCPUoption ) { // Server also monitor the system resource
	if ( (serverinfo = (struct SYSInfo *)malloc((setting.repeat + 2) 
			   * sizeof(struct SYSInfo))) == NULL ) {
	    perror("Failed to malloc.");
	    exit(1);
	}
	bzero(buff, BUFLEN);
	if ( tcp_get_request(sysbuff, &tcpsock) == NOTOK ||
	     string_to_sysinfo( &serverinfo[0], sysbuff, 2*BUFLEN) == NOTOK ) {
	    perror("Failed to get server's initial system information.");
	    exit (1);
	}
    }

    /******************** Print out the connection message *****************/

    if ( setting.verbose ) {
	fprintf(stderr, "UDP throughput %s test\n%s (client) <--> %s (server)\n", 
		setting.exponential ? "exponential" : "fixed packet size", localhost, hostname);
	fprintf(stderr, "UDP-port: %d UDP-send-buffer: %d UDP-recv-buffer: %d\n",
		udpsock.port, udpsock.sendBuf, udpsock.recvBuf);
    }

    /******************* Write test parameters to a file *******************/

    if ( setting.writeOption ) {

	get_local_time(curtime, BUFLEN);
	fprintf(output, "# UDP communication test -- %s\n", curtime);
	fprintf(output, "# %s size %s stream test\n", setting.exponential ? 
		"Exponential":"Fixed packet", setting.bidirection ? "bidirectional":"unidirectional");
	fprintf(output, "# Hosts: %s (client) <--> %s (server)\n\n", localhost, hostname);
	fprintf(output, "# Client UDP socket buffer size (Bytes) -- SNDBUF: %d RCVBUF: %d\n", 
		udpsock.sendBuf, udpsock.recvBuf );
	fprintf(output, "# Server UDP socket buffer size (Bytes) -- SNDBUF: %d RCVBUF: %d\n", 
		server.sendBuf, server.recvBuf);
	qos_type(&udpsock, buff);
	fprintf(output, "# Client IP TOS type: %s\n", buff);
	qos_type(&server, buff);
	fprintf(output, "# Server IP TOS type: %s\n", buff);
	fprintf(output, "# UDP datagram (packet) size (Bytes) -- Client: %d Server: %d\n", udpsock.packetSize, server.packetSize);

	if ( setting.exponential ) {  // Exponential test
	    fprintf(output, "# Test time (second): %f\n\n", setting.testTime);
	    if ( !setting.bidirection ) { 
		fprintf(output, "#   Size    Network     Local    Client      Client    Server      Server    Server  ServerRecv\n");
		fprintf(output, "#  (Byte)    (Mbps)    (Mbps)   SentPkg    SentByte   RecvPkg    RecvByte   LostPkg    LossRate  Timestamp\n");
	    } else {
		fprintf(output, "#   Size    Network     Local    Client      Client    Server      Server    Client      Client    Server      Server  ServerRecv\n");
		fprintf(output, "#  (Byte)    (Mbps)    (Mbps)   SentPkg    SentByte   RecvPkg    RecvByte   RecvPkg    RecvByte   SentPkg    SentByte    LossRate  Timestamp\n");
	    }
	}
	else { // Fixed packet size test
	    fprintf(output, "# Data size of each read/write (Bytes) -- Client: %d Server: %d\n", udpsock.dataSize, server.dataSize); 
	    fprintf(output, "# Message size (Bytes): %lld\n", setting.messageSize);
	    fprintf(output, "# Test time (Second): %f\n# Test repeat: %d\n\n", setting.testTime, setting.repeat); 

	    if ( ! setting.bidirection ) // One way unidirectional test
		fprintf(output, "#   Network(Mbps) Local(Mbps) SentPkg(C) SentByte(C) RecvPkg(S) RecvByte(S)  LostPkg  LossRate Timestamp\n");
	    else { // bidirection test 
		fprintf(output, "#     Network     Local    Client     Client    Server     Server    Client     Client    Server     Server   Server\n");
		fprintf(output, "#   throughput throughput   sent       sent      recv       recv      recv       recv      sent       sent     recv     Timestamp\n");
		fprintf(output, "#     (Mbps)     (Mbps)    packet      byte     packet      byte     packet      byte     packet      byte   loss-rate\n");
	    } // bidriection test
	} // Fixed packet size test

    } // If write option

    /********************** Start UDP throughput test **********************/ 

    for ( i = 0; i < setting.repeat; i++ ) {                   

	if ( setting.exponential ) {
		udpsock.dataSize = (1<<i);  // Increase the packet size doubly
		if ( udpsock.dataSize > udpsock.packetSize ) // The last one
		    udpsock.dataSize = udpsock.packetSize;
	}

	/**************** Inform server to start UDP test ******************/ 

	sprintf(buff, test_start_str, udpsock.dataSize, 0);
	if ( tcp_send_request(buff, strlen(buff), &tcpsock) == NOTOK ) {
	    perror("Failed to send request.");
	    client_shutdown();
	    exit (1);
	}

	/*************** Start monitoring system information ***************/

	if ( setting.CPUoption ) 
	    start_trace_system(&sysinfo[i+1]);
	start_trace_process(&proinfo[i]);

	/***************** Start UPD throughput test ***********************/

	if ( setting.bidirection ) {
	    if ( client_udp_bi_test (setting.messageSize, setting.testTime, &udpsock) 
		 == NOTOK && error != TIMEOUT && error != DISORDER ) {
		perror("UDP test error.");
		client_shutdown();
		exit (1);
	    }
	} else if ( client_udp_test (setting.messageSize, setting.testTime, &udpsock, 
		    setting.throughput) == NOTOK && error != TIMEOUT && error != DISORDER ) {
	    perror("UDP test error.");
	    client_shutdown();
	    exit (1);
	}

	stop_trace_process(&proinfo[i]);

	if ( setting.CPUoption ) {
	    usleep(1000);
	    stop_trace_system(&sysinfo[i+1]);
	}
	
#ifdef DEBUG 
	fprintf(stderr, " DEBUG: One trip test done, sent Bytes: %lld sent packets: %d\n",
		udpsock.sentBytes, udpsock.sentPackets);
	fprintf(stderr, " DEBUG: Waiting server's test result ...\n");
#endif 
	
	/************* Get server's test result by TCP channel *************/
	
	if ( tcp_get_request(buff, &tcpsock) == NOTOK ) {
	    fprintf(stderr, "Get result error (TCP data channel).\n");
	    client_shutdown();
	    exit(1);
	} else if ( strncmp(buff, test_time_out_str, strlen(test_time_out_str)) == 0 ) {
	    if ( setting.sCPUoption ) {
		if ( tcp_get_request(sysbuff, &tcpsock) == NOTOK ||
		     string_to_sysinfo( &serverinfo[i+1], sysbuff, 2*BUFLEN) == NOTOK ) {
		    perror("Failed to get server's system information.");
		    exit (1);
		}
	    }

	    fprintf(stderr, "UDP key packets lost. Igore the result.\n");
	    if ( setting.writeOption )
		fprintf (output, "#%d UDP key packets lost. Igore the result.\n", i+1);

	    s_rtime_usec[i] = s_utime_usec[i] = s_stime_usec[i] = 0;
	    continue;

	} else if ( sscanf(buff, server_result_str, &server.recvBytes, 
		    &server.recvPackets, &server.sentBytes, &server.sentPackets, 
		    &server.elapsedTime, &s_utime_usec[i], &s_stime_usec[i]) != 7 ) {
		fprintf(stderr, "Failed to parse server's result: %s\n", buff);
		client_shutdown();
		exit(1);
	}
	s_rtime_usec[i] = server.elapsedTime;

	if ( setting.sCPUoption ) {
	    if ( tcp_get_request(sysbuff, &tcpsock) == NOTOK ||
		 string_to_sysinfo( &serverinfo[i+1], sysbuff, 2*BUFLEN) == NOTOK ) {
		perror("Failed to get server's system information.");
		exit (1);
	    }
	}	

	localTP.trial++;
	networkTP.trial++;

	if ( server.elapsedTime <= 0 ) {
	    fprintf(stderr, "Wrong of server's elapsed time! Ignore the result: %s\n", buff);
	    continue;
	}
	
	serverTP = (server.recvBytes+udpsock.recvBytes) * 8.0 / server.elapsedTime; // Network count
	
	if ( networkTP.min > serverTP )
	    networkTP.min = serverTP;
	if ( networkTP.max < serverTP )
	    networkTP.max = serverTP;
	networkTP.sum += serverTP;
	
	clientTP = (server.sentBytes+udpsock.sentBytes) * 8.0 / udpsock.elapsedTime; // local count
	proinfo[i].rtime_sec = udpsock.elapsedTime / 1000000;
	proinfo[i].rtime_usec = udpsock.elapsedTime % 1000000;
	
	/************* Keep the minimum and maximum throughputs ************/	    
	
	if ( localTP.min > clientTP )
	    localTP.min = clientTP;
	if ( localTP.max < clientTP )
	    localTP.max = clientTP;
	localTP.sum += clientTP;

	/****** Compute the packet loss rate of client sending *************/
	
	lossPackets = udpsock.sentPackets - server.recvPackets;
	lossRate = lossPackets * 1.0 / udpsock.sentPackets;
	
	/*********************** Print out test results ********************/ 
	    
	if ( setting.verbose ) {
	    if ( setting.exponential )	
		fprintf(stderr, "Message size: %d\n", udpsock.dataSize);
	    fprintf(stderr, "\n[Client] Sent-bytes: %lld Sent-packets: %d ", 
		    udpsock.sentBytes, udpsock.sentPackets);
	    fprintf(stderr, "Recv-bytes: %lld Recv-Packets: %d\n", 
		    udpsock.recvBytes, udpsock.recvPackets);
	    fprintf(stderr, "[Server] Recv-bytes: %lld Recv-Packets: %d ", 
		    server.recvBytes, server.recvPackets);
	    fprintf(stderr, "Sent-bytes: %lld Sent-Packets: %d\n", 
		    server.sentBytes, server.sentPackets);
	    fprintf(stderr, "Client-time(Sec.): %f  Server-time(Sec.): %f\n", 
		    udpsock.elapsedTime/1000000.0, server.elapsedTime/1000000.0);
	    fprintf(stderr, "Network-throughput(Mbps): %f Local-throughput: %f\n", 
		    serverTP, clientTP);
	    fprintf(stderr, "Lost-packets (c->s): %d  Loss-rate(c->s): %f\n\n", 
		    lossPackets, lossRate);
	} else
	    fprintf(stderr, " (%d) Throughput: %f  Loss-rate: %f\n", 
		    i+1, serverTP, lossRate);
	    
	/*************** Store test results in the file ********************/

    gettimeofday(&tv, NULL);
    ts = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
	if ( setting.writeOption ) {
	    if ( setting.exponential ) {     // exponential throughput test
		if ( !setting.bidirection )
		    fprintf (output, "%-3d%6d%10.3f%10.3f%10d%12lld%10d%12lld%10d%10.3f%17.2f\n", 
			 i+1, udpsock.dataSize, serverTP, clientTP, udpsock.sentPackets, 
			 udpsock.sentBytes, server.recvPackets, server.recvBytes, 
			 lossPackets, lossRate, ts);
		else
		    fprintf (output, "%-3d%6d%10.3f%10.3f%10d%12lld%10d%12lld%10d%12lld%10d%12lld%12.3f%17.2f\n", 
			 i+1, udpsock.dataSize, serverTP, clientTP, udpsock.sentPackets, 
			 udpsock.sentBytes, server.recvPackets, server.recvBytes, udpsock.recvPackets, 
			     udpsock.recvBytes, server.sentPackets, server.sentBytes, lossRate, ts);
	    }
	    else if ( !setting.bidirection )   // unidirectional throughput test 
		fprintf (output, "%-3d%13.4f%12.4f%11d%12lld%11d%12lld%10d%10.3f%17.2f\n", 
			 i+1, serverTP, clientTP, udpsock.sentPackets, udpsock.sentBytes, 
			 server.recvPackets, server.recvBytes, lossPackets, lossRate, ts);
	    else {                             // bidirectional throughput test 
		fprintf(output, "%-3d%10.3f%11.3f%9d", i+1, serverTP, clientTP, udpsock.sentPackets);
		fprintf(output, "%12lld%9d%12lld", udpsock.sentBytes, server.recvPackets, server.recvBytes);
		fprintf(output, "%9d%12lld%9d", udpsock.recvPackets, udpsock.recvBytes, server.sentPackets);
		fprintf(output, "%12lld%9.3f%17.2f\n", server.sentBytes, lossRate, ts);
	    } // bidriection test
	} // if write option

    } // for loop of repeat


    /********************** Inform server the end of the session ***********/

    sprintf(buff, test_end_str);
    if ( tcp_send_request (buff, strlen(buff), &tcpsock) == NOTOK )
	fprintf(stderr, "Close session error.");

    if ( setting.CPUoption ) { // record the post-test system info
	if ( start_trace_system( &sysinfo[setting.repeat+1] ) == NOTOK ) {
	    perror("Failed to trace system in final state.");
	    exit (1);
	}
	sleep(1);
	if ( stop_trace_system( &sysinfo[setting.repeat+1] ) == NOTOK ) {
	    perror("Failed to trace system in final state.");
	    exit (1);
	}
	if ( setting.sCPUoption ) {
	    if ( tcp_get_request(sysbuff, &tcpsock) == NOTOK ||
		 string_to_sysinfo( &serverinfo[setting.repeat+1],
				    sysbuff, 2*BUFLEN) == NOTOK ) {
		perror("Failed to get server's last syslog.");
		exit (1);
	    }
	}
    }

    /***** Compute the average throughput for fixed-size message tests *****/

    if ( !setting.exponential && setting.writeOption && localTP.trial > 2 ) {
	
	localTP.avg = localTP.sum/localTP.trial; 
	networkTP.avg = networkTP.sum/localTP.trial; 

	fprintf(output, "\n# Local Average: %10f  Minimum: %10f  Maximum: %10f\n", 
		localTP.avg, localTP.min, localTP.max);
	fprintf(output, "# Network Average: %10f  Minimum: %10f  Maximum: %10f\n", 
		networkTP.avg, networkTP.min, networkTP.max);
    } 

    if ( setting.writeOption ) {
	fprintf(output, "\n# Process information for each test: \n\n");
	fprintf(output, "#         Client     C-process   C-process      Server     S-process   S-process\n");
	fprintf(output, "#      Elapsed-time  User-mode  System-mode  Elapsed-time  User-mode  System-mode\n");
	fprintf(output, "#       (Seconds)    (Seconds)   (Seconds)    (Seconds)    (Seconds)   (Seconds)\n");
	for ( i = 0; i < setting.repeat; i++ ) {
	    fprintf(output, "#%-4d%11.2f%13.2f%12.2f%13.2f%13.2f%12.2f\n", i+1, 
		    (double)proinfo[i].rtime_sec + proinfo[i].rtime_usec/1000000.0,
		    (double)proinfo[i].utime_sec + proinfo[i].utime_usec/1000000.0,
		    (double)proinfo[i].stime_sec + proinfo[i].stime_usec/1000000.0,
		    s_rtime_usec[i]/1000000.0, s_utime_usec[i]/1000000.0, s_stime_usec[i]/1000000.0);
	}
	fprintf(output, "\n");
	fclose(output); 

	fprintf(stderr, "Test done! The results are stored in file \"%s\"\n", filename);
	if ( setting.CPUoption ) {
	    strcpy(buff, filename);
	    strcat(buff, ".c_log");
	    if ( write_sys_info(sysinfo, setting.repeat+2, buff, curtime, localhost) == OK )
		fprintf(stderr, "Local-syslog: \"%s\"  ", buff); 
	    strcpy(buff, filename);
	    strcat(buff, ".s_log");
	    if ( setting.sCPUoption && 
		 write_sys_info(serverinfo, setting.repeat+2, buff, curtime, hostname) == OK )
		fprintf(stderr, "server-syslog: \"%s\"", buff); 
	    fprintf(stderr, "\n");
	}	
	if ( setting.plotOption && write_plot() == OK ) { 
	    fprintf(stderr, "Plot-file: \"%s\". ", plotname);
	    fprintf(stderr, "Use \"gnuplot %s\" to plot the data\n", plotname);
	}
	fclose(output);
    } else 
	fprintf(stderr, "Test done!\n");

    /*************************** Close the connection **********************/

    client_shutdown();   
    return 0;

}  // end of main function