#!/usr/local/bin/perl ############################################################################### # Program : main.cgi # Author : Eric Deutsch # $Id$ # # Description : This script authenticates the user, and then # displays the opening access page. # # SBEAMS is Copyright (C) 2000-2005 Institute for Systems Biology # This program is governed by the terms of the GNU General Public License (GPL) # version 2 as published by the Free Software Foundation. It is provided # WITHOUT ANY WARRANTY. See the full description of GPL terms in the # LICENSE file distributed with this software. # ############################################################################### ############################################################################### # Get the script set up with everything it will need ############################################################################### use strict; use Alcyt; use Text::Wrap; use Data::Dumper; use GD::Graph::xypoints; use vars qw ($q $sbeams $sbeamsMOD $PROGRAM_FILE_NAME $current_contact_id $current_username); use lib qw (../../lib/perl); #use CGI; use CGI::Carp qw(fatalsToBrowser croak); use SBEAMS::Connection qw($q); use SBEAMS::Cytometry; use SBEAMS::Cytometry::Settings; use SBEAMS::Cytometry::Tables; use SBEAMS::Connection::Settings; use SBEAMS::Connection::DBConnector; use SBEAMS::Connection::Tables; use SBEAMS::Connection::TableInfo; use SBEAMS::Connection::Utilities; #$q = new CGI; $sbeams = new SBEAMS::Connection; $sbeamsMOD = new SBEAMS::Cytometry; $sbeamsMOD->setSBEAMS($sbeams); ############################################################################### # Global Variables ############################################################################### my $VERBOSE; my $TESTONLY; $PROGRAM_FILE_NAME = 'main.cgi'; my $INTRO = '_displayIntro'; my $START = '_start'; my $ERROR = '_error'; my $PROCESSFILE = '_processFile'; my $GETGRAPH = '_getGraph'; my $CELL = '_processCells'; my $GETANOTHERGRAPH = '_getAnotherGraph'; my (%indexHash,%editorHash,%inParsParam); #possible actions (pages) displayed my %actionHash = ( $INTRO => \&displayIntro, $START => \&displayMain, $PROCESSFILE => \&processFile, $GETGRAPH => \&getGraph, $CELL => \&processCells, $ERROR => \&processError, $GETANOTHERGRAPH => \&getAnotherGraph ); my %optionHash = ( 'FLS' => 'fl', 'RED' => 're', 'PLS' => 'pl', 'BLUE' => 'bl', 'GREEN' => 'gr', 'pulse width' => 'pw', 'LOG(FLS)' => 'fl', 'Hoechst Red' => 're', 'Hoechst red' => 're', 'ADC12' => 'aaa', 'ADC12' => 'bbb', 'LOG(PLS)' => 'pl', 'Hoechst Blue' => 'bl', 'Hoechst blue' => 'bl', 'xxx' => 'wave', 'LUT DECISION' => 'lut', 'CLASS DECISION' =>'cls', 'COUNTER' => 'cts', 'yyy' => 'spec', 'www' => 'gr', 'zzz' => 'rate', 'qqq' => 'time', 'uuu' => 'event No.' ); my %indexHash = ( ' event No.' => 0, time => 1, rate => 2, cls => 3, cts => 4, lut => 5, pw => 6, fl => 7, pl => 8, wave => 9, spec => 10, bl => 11, gr => 12, re => 13); my %columnHash = $sbeams->selectTwoColumnHash("Select upper(file_Column),database_column from $TBCY_CONVERSION_DATA"); main(); exit(0); ############################################################################### # Main Program: # # Call $sbeams->Authentication and stop immediately if authentication # fails else continue. ############################################################################### sub main { #### Do the SBEAMS authentication and exit if a username is not returned exit unless ($current_username = $sbeams->Authenticate( #connect_read_only=>1, allow_anonymous_access=>1, # permitted_work_groups_ref=>['Cytometry_user','Cytometry_admin','Admin'], )); #### Read in the default input parameters my %parameters; my $n_params_found = $sbeams->parse_input_parameters( q=>$q,parameters_ref=>\%parameters); #$sbeams->printDebuggingInfo($q); #### Process generic "state" parameters before we start $sbeams->processStandardParameters(parameters_ref=>\%parameters); #### Print the header, do what the program does, and print footer # normal handling for anything else $sbeamsMOD->display_page_header(); handle_request(ref_parameters=>\%parameters); $sbeamsMOD->display_page_footer(); } # end main ############################################################################### # Show the main welcome page ############################################################################### sub handle_request { my %args = @_; #### Process the arguments list my $ref_parameters = $args{'ref_parameters'} || die "ref_parameters not passed"; my %parameters = %{$ref_parameters}; #### Define some generic varibles my ($i,$element,$key,$value,$line,$result,$sql); my @rows; $current_contact_id = $sbeams->getCurrent_contact_id(); #### Show current user context information $sbeams->printUserContext(); #### Get information about the current project from the database $sql = qq~ SELECT UC.project_id,P.name,P.project_tag,P.project_status, P.PI_contact_id FROM $TB_USER_CONTEXT UC INNER JOIN $TB_PROJECT P ON ( UC.project_id = P.project_id ) WHERE UC.contact_id = '$current_contact_id' ~; @rows = $sbeams->selectSeveralColumns($sql); my $project_id = ''; my $project_name = 'NONE'; my $project_tag = 'NONE'; my $project_status = 'N/A'; my $PI_contact_id = 0; if (@rows) { ($project_id,$project_name,$project_tag,$project_status,$PI_contact_id) = @{$rows[0]}; } my $PI_name = $sbeams->getUsername($PI_contact_id); #### If the current user is not the owner, the check that the #### user has privilege to access this project if ($project_id > 0) { my $best_permission = $sbeams->get_best_permission(); #### If not at least data_reader, set project_id to a bad value $project_id = -99 unless ($best_permission > 0 && $best_permission <=40); } #### Get all the experiments for this project my $action = $parameters{'action'}; print qq~ ~; my $sub = $actionHash{$action} || $actionHash{$INTRO}; #loading the default page (Intro) #my $sub = $actionHash{$action} || $actionHash{$INTRO}; if ($sub ) { #print some info about this project #only on the main page print qq~

Current Project: $project_name

Status: $project_status
Project Tag: $project_tag
Owner: $PI_name
Access Privileges: [View/Edit]
~ if ($action eq '_displayIntro' || !$action) ; checkGO(); #### If the project_id wasn't reverted to -99, display information about it if ($project_id == -99) { print " \n"; } else { &$sub(ref_parameters=>\%parameters,project_id=>$project_id); } #could not find a sub } else { print_fatal_error("Could not find the specified routine: $sub"); } print "
You do not have access to this project. Contact the owner of this project if you want to have access.
"; } ####---------------------------------------------------------------------------------- sub displayIntro { my %args = @_; #### get the project id # my $project_id = $args{'project_id'} || die "project_id not passed"; my $organismSql = qq~ select organism_id,organism_name from sbeams.dbo.organism ~; my %organismHash = $sbeams->selectTwoColumnHash($organismSql); my $sql = "select fcs_run_id,Organism_id , project_designator, sample_name, filename, run_date from $TBCY_FCS_RUN order by project_designator"; #where project_id = '$project_id' order by project_designator"; my @rows = $sbeams->selectSeveralColumns($sql); my %hashFile; my $count = 1; if (@rows) { print "

Current Cytometry data for this project


"; print ""; foreach my $row(@rows) { my ($fcsID,$organismID, $projectDes, $sampleName, $fileName, $runDate) = @{$row}; $runDate =~ s/^(.*?)\s0.*$/$1/; my @array; # print "$count == $projectDes == $organismID == ,$sampleName == $fileName === $runDate
"; $projectDes = uc($projectDes); push @array,( $sampleName, $organismHash{$organismID},$fileName, $runDate); # $hashFile{$projectDes}->{$fcsID} = \ @array; $hashFile{$projectDes}->{$fcsID}->{'Sample Name'} = $sampleName; $hashFile{$projectDes}->{$fcsID}->{Organism} = $organismHash{$organismID}; $hashFile{$projectDes}->{$fcsID}->{'File Name'} = $fileName; $hashFile{$projectDes}->{$fcsID}->{'Run Date'} = $runDate; $hashFile{$projectDes}->{$fcsID}->{'Create Graph'} = $fileName; $count++; } foreach my $key (keys %hashFile) { print ""; print ""; foreach my $id (keys %{$hashFile{$key}}) { print qq ~~; } } } else { print " \n"; } #### Finish the table print qq~
Project Designator: $key
Sample NameOrganismFile NameRun DateCreate Graph
$hashFile{$key}->{$id}->{'Sample Name'} $hashFile{$key}->{$id}->{Organism} $hashFile{$key}->{$id}->{'File Name'} $hashFile{$key}->{$id}->{'Run Date'} Create Graph
This project contains no Cytometry Data
~; ########################################################################## #### Print out all projects owned by the user $sbeams->printProjectsYouOwn() if $sbeams->getCurrent_contact_id(); ########################################################################## #### Print out all projects user has access to $sbeams->printProjectsYouHaveAccessTo() if $sbeams->getCurrent_contact_id(); ########################################################################## #### Print out some recent resultsets $sbeams->printRecentResultsets() if $sbeams->getCurrent_contact_id(); ########################################################################## #### Finish with a disclaimer print qq~

This system and this module in particular are still under active development. Please be patient and report bugs, problems, difficulties, as well as suggestions to edeutsch\@systemsbiology.org.



~; return; } # end showMainPage sub processFile { my %args = @_; #### Process the arguments list my $ref_parameters = $args{'ref_parameters'} || die "ref_parameters not passed"; my %parameters = %{$ref_parameters}; my %resultset = (); my $resultset_ref = \%resultset; my %parameters = %{$ref_parameters}; =comment foreach my $k (keys %parameters) { print "$k ==== $parameters{$k}
"; } =cut my $fileQuery = "select original_filepath +'/' + filename as completeFile from $TBCY_FCS_RUN where fcs_run_id = $parameters{fileID}"; my $storeFile = "$PHYSICAL_BASE_DIR/images/tmp/$parameters{fileID}"."\.txt"; if (-e $storeFile and !$parameters{storeFile}) { unlink $storeFile; } my @row = $sbeams->selectOneColumn($fileQuery); my $infile = $row[0]; #'/net/db/projects/StemCell/FCS/102403/'.$parameters{fileName}; my @header = read_fcs_header($infile); my @keywords = get_fcs_keywords($infile,@header); my %values = get_fcs_key_value_hash(@keywords); if (! $parameters{graphNum}) { print "

Assembling the data points.



"; print "

Number of parameters measured: $values{'$PAR'}

"; print "Measured parameters:
"; print "Choose the X and Y coordinates
"; } # my $string; my (%cytoParameters) ; foreach my $key (keys %values) { if ($key =~ /\$P(\d+)N/i) { my $position = $1; $values{$key} =~ s/^[\s\n]+//g; $values{$key} =~ s/[\s\n]+$//g; next if $values{$key} =~ /adc/i; $cytoParameters{$key} = $values{$key}; # $postionHash{$optionHash{$values{$key}}} = $1; # $string .= " -".$optionHash{$values{$key}}." ".$1; } } if ($values{'$PAR'}) { # checkGo(); print qq~
~if (! $parameters{graphNum}); print qq ~~ ; my $staticMinX = $parameters{minX}; my $staticMaxX = $parameters{maxX}; my $staticMinY = $parameters{minY}; my $staticMaxY = $parameters{maxY}; my (@xOptionArray, @yOptionArray); while ($parameters{minX} < $parameters{maxX}) { # next if ! defined($parameters{minX}); push @xOptionArray, $parameters{minX}; $parameters{minX} += 200; } while ($parameters{minY} < $parameters{maxY}) { # next if ! defined($parameters{minY}); push @yOptionArray, $parameters{minY}; $parameters{minY} += 200; } my $count = 0; print qq~"; print qq~~; print qq~~; print qq~ ~; print "
~ if ($parameters{graphNum}); print qq~ \n~; print qq~ ~; print $q->start_form (-onSubmit=>"return checkRadioButton()") if (! $parameters{graphNum}); print $q->start_form (-onSubmit=>"return checkAnotherRadioButton()") if ($parameters{graphNum}); print qq ~ ~ if( $parameters{graphNum}); foreach my $key (keys %cytoParameters) { my $upperKey = uc($cytoParameters{$key}); if ( ! $parameters{graphNum}) { print qq~ \n~; } else { print qq~ \n ~; print qq~ \n~; } } print qq~ ~; if ( ! $parameters{graphNum}) { print qq~ ~ ; print qq~
x-axisy-axis

Create a new graph based on this graph's X and Y datapoints
by specifying the range of the datapoints
$cytoParameters{$key}~; print qq~ $cytoParameters{$key}
$cytoParameters{$key}$cytoParameters{$key}
~; } else { print qq ~
Select min X-coordinates Select min Y-coordinates
Select max X-coordinates Select max Y-coordinates
"; } print $q->end_form; } else { print "



Unable to process file: $infile.
$!

Please see your Admin

"; } } # Read in the header to determine where the text and data sections are in # in the file. sub getAnotherGraph { my %args = @_; #### Process the arguments list my $ref_parameters = $args{'ref_parameters'} || die "ref_parameters not passed"; my %parameters = %{$ref_parameters}; my %resultset = (); my $resultset_ref = \%resultset; my %parameters = %{$ref_parameters}; =comment foreach my $k (keys %parameters) { print "$k ==== $parameters{$k}
"; } =cut my $parametersRef = createGraph( \%parameters); printGraph ($parametersRef); } sub getGraph { my %args = @_; #### Process the arguments list my $ref_parameters = $args{'ref_parameters'} || die "ref_parameters not passed"; my %parameters = %{$ref_parameters}; my %resultset = (); my $resultset_ref = \%resultset; my %parameters = %{$ref_parameters}; =comment foreach my $k (keys %parameters) { print "$k ==== $parameters{$k}
"; } =cut my $infile = $parameters{inFile}; # Strip out all of the keyword-value pairs. my @header = read_fcs_header($infile); my @keywords = get_fcs_keywords($infile,@header); my %values = get_fcs_key_value_hash(@keywords); foreach my $key (keys %values) { if ($key =~ /\$P(\d+)N/i) { my $position = $1; $values{$key} =~ s/^[\s\n]+//g; $values{$key} =~ s/[\s\n]+$//g; next if $values{$key} =~ /adc/i; $inParsParam{$optionHash{$values{$key}}} = $1; } } # Write the header parameters to the output file. # Also add the standard column headings. my $num_events = $values{'$TOT'}; print "
Number of events: $num_events\n
"; my $num_par = $values{'$PAR'}; my %inpars = (); ($inpars{timelow},$inpars{timehigh}) = get_time_par(@keywords); $inpars{lut} = get_lut_par(@keywords); $inpars{cls} = get_cls_par(@keywords); $inpars{cts} = get_cts_par(@keywords); $inpars{pw} = $inParsParam{pw} || 0; #get_pw_par(@keywords); $inpars{fls} = $inParsParam{fl} || 0; $inpars{pls} = $inParsParam{pl} || 0; $inpars{wave} = $inParsParam{wave} || 0; $inpars{spec} = $inParsParam{spec} || 0; $inpars{blue} = $inParsParam{bl} || 0; $inpars{green} =$inParsParam{gr} || 0;; $inpars{red} = $inParsParam{re} || 0; data2($infile,$header[3],2,$num_par,$num_events,%inpars); my $parametersRef = createGraph( \%parameters); printGraph ($parametersRef); } # # sub printGraph { my $parameterRef = shift; $parameterRef->{graphNum} =1; my $imgsrcbuffer = ' '; open (TXT, "$parameterRef->{storeFile}") or die $!; my $count =1; my @imageArray; while (my $imageFile = ) { chomp $imageFile; push @imageArray,$imageFile; } my $prevImage = "xxxx"; foreach my $image (@imageArray) { next if $image =~ /$prevImage/i and do $count --;; if ($count == 1) { # my $imgsrcbuffer =' '; $imgsrcbuffer = ""; print qq~ $imgsrcbuffer ~; processFile(ref_parameters=>$parameterRef); print ""; } else { print qq~~if (!$count%2); my $imgsrcbuffer =' '; $imgsrcbuffer = ""; print " $imgsrcbuffer "; print "" if ($count%2); } $prevImage = "_orig"; $count ++; } print ""; } #create radio button and x - y min and max #regraph this with the original graph and other graphs #create hidden field to know how many time this page appeared sub createGraph { my ($paramRef) = @_; =comment foreach my $key (keys %{$paramRef}) { print "this is before $key === $paramRef->{$key}
"; } =cut my $xMinCoor = $paramRef->{xBoxMin} || 0; my $xMaxCoor = $paramRef->{xBoxMax} || 1000000; my $yMinCoor = $paramRef->{yBoxMin} || 0; my $yMaxCoor = $paramRef->{yBoxMax} || 1000000; my $xCoorAnother = $paramRef->{xboxAnother}; my $yCoorAnother = $paramRef->{yboxAnother}; my $xCoor = $paramRef->{xbox}; my $yCoor = $paramRef->{ybox}; my $fileID = $paramRef->{fileID}; my $inFile = $paramRef->{inFile}; my ($fileName) = $inFile =~ /^.*\/(.*)$/; my $maxX = $paramRef->{maxX} || 0; my $maxY =$paramRef->{maxY} || 0; my $minX = 1000000; $minX = $paramRef->{minX} if defined($paramRef->{minX}); my $minY = 1000000; $minY = $paramRef->{minY} if defined($paramRef->{minY}); my (@xArray,@yArray); my @rows = []; #first Graph my $graphQuery = "Select $xCoor,$yCoor from $TBCY_DATA_POINTS cy join $TBCY_FCS_RUN fc on cy. fcs_run_id = fc.fcs_run_id where filename = \'$fileName\'"; @rows = $sbeams->selectSeveralColumns($graphQuery) if (!$paramRef->{graphNum}); #all subsequent Graphs my $anotherGraphQuery = "Select $xCoorAnother, $yCoorAnother from $TBCY_DATA_POINTS cy where cy.data_points_id in (select data_points_id from $TBCY_DATA_POINTS where $xCoor > $xMinCoor and $xCoor < $xMaxCoor and $yCoor > $yMinCoor and $yCoor < $yMaxCoor and fcs_run_id = $fileID)"; @rows = $sbeams->selectSeveralColumns($anotherGraphQuery) if ($paramRef->{graphNum}); my $count = 0; foreach my $row (@rows) { next if $count%5 and (!$paramRef->{graphNum}); my ($xData, $yData) = @{$row}; $maxX = $xData if ($maxX <$xData and (!$paramRef->{graphNum})); $minX = $xData if ($minX > $xData and (!$paramRef->{graphNum})); push @xArray,$xData; $maxY = $yData if ($maxY <$yData and (!$paramRef->{graphNum})); $minY = $yData if ($minY > $yData and (!$paramRef->{graphNum})); push @yArray,$yData; } my $tmpfile; $tmpfile = "plot.$$.@{[time]}_orig.png" if (!$paramRef->{graphNum}); $tmpfile = "plot.$$.@{[time]}.png" if ($paramRef->{graphNum}); my @data=([@xArray],[@yArray]); #foreach my $pp (keys %{$paramRef}) #{ # print "$pp === $paramRef->{$pp}
"; #} my $xLabel = $xCoor; $xLabel = $xCoorAnother if ($xCoorAnother); my $yLabel = $yCoor; $yLabel = $yCoorAnother if ($yCoorAnother); my $graph; $graph = GD::Graph::xypoints->new(500,380) if (! $paramRef->{graphNum} ); $graph = GD::Graph::xypoints->new(350,230) if ($paramRef->{graphNum} ); if (! $paramRef->{graphNum} ) { $graph->set( x_label =>$xLabel, y_label => $yLabel, title => $inFile, x_number_format => \&formatNum, y_number_format => \&formatNum, x_tick_number => 25, y_tick_number => 25, long_ticks => 0, markers => 7, show_value => 1, marker_size => .1, x_max_value =>$maxX, y_max_value => $maxY ); } else { $graph->set( x_label =>$xLabel, y_label => $yLabel, x_number_format => \&formatNum, y_number_format => \&formatNum, x_tick_number => 10, y_tick_number => 10, long_ticks => 0, markers => 7, show_value => 1, marker_size => .1, ); } my $gd = $graph->plot(\@data); open(IMG, ">$PHYSICAL_BASE_DIR/images/tmp/$tmpfile") or die $!; binmode IMG; print IMG $gd->png; close IMG; #### Provide the link to the image my $imageFile = "$HTML_BASE_DIR/images/tmp/$tmpfile"; open (TXT, ">>$paramRef->{storeFile}") or die $!; print TXT "$imageFile\n"; close TXT; $paramRef-> {maxX} = $maxX; $paramRef-> {maxY} = $maxY; $paramRef-> {minX} = $minX; $paramRef-> {minY} = $minY; =comment foreach my $key (keys %{$paramRef}) { print "this is create Graph $key === $paramRef->{$key}
"; } =cut return ($paramRef); } sub formatNum { my $value = shift; $value =~ s/^(\d+)\.\d*$/$1/; return $value; } sub data2 { my $infile = shift(@_); my $offset = shift(@_); my $size = shift(@_); # not used my $n_params = shift(@_); my $n_events = shift(@_); my %incol = @_; # This hash contains the column assignments for the # parameters in the input datafile. See the main # code for details. my ($fileName) = $infile =~ /^.*\/(.*)$/; # Next, we deal with any parameters which are not amoung the "standard # set". There is probably a slicker way to do this but I don't have # time to think about it right now. # Define an array which contains the indices of all parameters. my( @cols,@unnamed); for (my $i = 1; $i <= $n_params; $i++) { $cols[$i] = $i; } while ((my($key,$value)) = each %incol) { $cols[$value] = 0; } my $j = 0; for (my $i = 1; $i <= $n_params; $i++) { if ($cols[$i] != 0) { $unnamed[$j] = $cols[$i]; $j++; } } open(FCSFILE,"$infile") or die "dump_data: Can't find input file $infile."; # Throw away all of the bits up to the data part of the file. my $pre_text = $offset; my $dummy = ""; read(FCSFILE,$dummy,$offset); # Initialize the event array. my @firstevent = (); my $data; # Read the first event in order to get the starting time. for (my $param = 1; $param <= $n_params; $param++) { read(FCSFILE,$data,2); $firstevent[$param] = unpack("S",$data); } my $time0 = ( $firstevent[$incol{timelow}]) + 4096 * ($firstevent[$incol{timehigh}] ); close(FCSFILE); # For ease of understanding the code and to avoid # duplicating code, we close the file, then re-open # it and read in the first event again along with the # rest of the data. # Read in the data, sort it out into the correct columns, and dump # it to the output file. open(FCSFILE,"$infile") or die "dump_data2: Can't find input file $infile."; read(FCSFILE,$dummy,$offset); # read over header and text sections. my $fileID = 0; my $query = "Select top 1dp. fcs_run_id from $TBCY_DATA_POINTS dp left join $TBCY_FCS_RUN fcs on dp.fcs_run_id = fcs.fcs_run_id where fcs.filename = \'$fileName\'"; my @rows = $sbeams->selectOneColumn($query); $fileID = $rows[0] if scalar(@rows == 1);; if ($fileID) { return; } else { my $fileQuery = "Select fcs_run_id from $TBCY_FCS_RUN where filename = \'$fileName\'"; my @rows = $sbeams->selectOneColumn($fileQuery); my $runID = $rows[0]; my @event; for (my $event_num = 1 ; $event_num <= $n_events; $event_num++) { for (my $param = 1; $param <= $n_params; $param++) { # This assumes a 16 bit data word. Not the best way to do this. read(FCSFILE,$data,2); $event[$param] = unpack("S",$data); } # Compute the time from the two 12-bit values. Subtract off the # time of the earliest event in the file. # June 12, 2003. Change this to not subtract off the initial time # to allow concatenation of multiple files while preserving the time. # $time = $event[$incol{timelow}] + 4096 * ($event[$incol{timehigh}]) - $time0; my $time = $event[$incol{timelow}] + 4096 * ($event[$incol{timehigh}]); my $insert = 1; my $update = 0; my $pK = 0; my %dataHash; $dataHash{lut} = $event[$incol{lut}]; $dataHash{cls} = $event[$incol{cls}]; $dataHash{cts} = $event[$incol{cts}]; $dataHash{pw}= $event[$incol{pw}]; $dataHash{fls} = $event[$incol{fls}]; $dataHash{pls} = $event[$incol{pls}]; $dataHash{wave} = $event[$incol{wave}]; $dataHash{spec} = $event[$incol{spec}]; $dataHash{blue} = $event[$incol{blue}]; $dataHash{green} = $event[$incol{green}]; $dataHash{red} = $event[$incol{red}]; $dataHash{fcs_run_id} = $runID; my $returned_PK = $sbeams->updateOrInsertRow( insert => $insert, update => $update, table_name => "$TBCY_DATA_POINTS", rowdata_ref => \%dataHash, PK => "data_points_id", PK_value => $pK, return_PK => 1, verbose=>$VERBOSE, testonly=>$TESTONLY, add_audit_parameters => 1 ); } } close(FCSFILE); } sub printMessage { print "
This is first time this file has been accessed.
Data points need to loaded into the Database.
This may take a few minutes.
Please be patient

"; return; } sub checkGO { print q~