Instruction: Write an abstract for the following acadamic paper.

Input:
Paper: we have recorded the flight of a fly during take off and landing using digital high speed photography . it is shown that the dynamics of flexible wings are different for these procedures . during this observation fly flew freely in a big box and it was not tethered .
Abstract: in this fluid dynamics video , we demonstrated take off and landing of a fly . the deformation of wings is in focus in this video .

Paper: a typical scientific research project requires a variety of computational tasks to be performed . at the very heart of every investigation is the generation of data to test hypotheses . an experimental physicist builds instruments to collect light scattering data ; a crystallographer collects x - ray diffraction data ; a biologist collects fluorescence intensity data for reporter genes , or dna sequence data for these genes ; and a computational researcher writes programs to generate simulation data . all of these scientists use computer programs to control instruments or perform simulations to collect and manage data in an electronic format . once data is collected , the next task is to analyze it in the context of hypothesis - driven models that help them understand the phenomenon they are studying . in the case of light , or x - ray scattering data , there is a well - proven physical theory that is used to process the data and calculate the observed structure function of the material being studied @xcite . this structure function is then compared to predictions made by the hypotheses begin tested . in the case of biological reporter gene data , light intensity is matched up with phenotypic traits or dna sequences , and statistically analyzed for trends that might explain the observed patterns . as these examples illustrate , across science , the original raw data of each investigation is extensively processed by computational programs in an effort to understand the underlying phenomena . visualization tools to create a variety of scientific plots are often a preferred tool for both troubleshooting ongoing experiments , and creating publication - quality scientific plots and charts . these plots and charts are often the final product of a scientific investigation in the form of data - rich graphics that demonstrate the truth of a hypothesis compared to its alternatives @xcite . unfortunately , all too often scientists resort to a grab - bag of tools to perform these varied computational tasks . for physicists and theoretical chemists , it is common to use c or fortran to generate simulation data , and c code is used to control experimental apparatus ; for biologists , perl is the language of choice to manipulate dna sequence data @xcite . data analysis is performed in separate , external software packages such as matlab or mathematica for equation solving @xcite , or stata , spss or r for statistical calculations @xcite . furthermore , separate data visualization packages can be used , making the scientific programming toolset extremely varied . such a mixed bag of tools is an inadequate solution for a variety of reasons . from a computational perspective , most of these tools can not be pipelined easily which necessitates many manual steps or excessive glue code that most scientists are not trained to write . far more important than just an inconvenience associated with gluing these tools together is the extreme burden placed on the scientist in terms of data management . in complicated systems , there are often a plethora of different data files in several different formats residing at many different locations . most tools do not produce adequate metadata for these files , and scientists typically fall back on cryptic file naming schemes to indicate what type of data the files contain and how it was generated . such complications can easily lead to mistakes . this in turn provides poor at best data provenance when it is in fact of utmost importance in scientific studies where data integrity is the foundation of every conclusion reached and every fact established . furthermore , when data files are manually moved around from tool to tool , it is not clear if an error is due to program error , or human error in using the wrong file . analyses can only be repeated by following work flows that have to be manually recorded in a paper or electronic lab notebook . this practice makes steps easily forgotten , and hard to pass on to future generations of scientists , or current peers trying to reproduce scientific results .    the python programming language and associated community tools @xcite can help scientists overcome some of these problems by providing a general scientific programming platform that allows scientists to generate , analyze , visualize and manage their data within the same computational framework . python can be used to generate simulation data , or control instrumentation to capture data . data analysis can be accomplished in the same way , and there are graphics libraries that can produce scientific charts and graphs . furthermore python code can be used to glue all of these python solutions together so that visualization code resides alongside the code that generates the data it is applied to . this allows streamlined generation of data and its analysis , which makes data management feasible . most importantly , such a uniform tool set allows the scientist to record the steps used in data work flows to be written down in python code itself , allowing automatic provenance tracking .    in this paper , we outline a recent comparative genomics case study where python and associated community libraries were used as a complete scientific programming platform . we introduce several specific python libraries and tools , and how they were used to facilitate input of standardized biological data , create scientific plots , and provide solutions to speed bottle - necks in the code . throughout , we provide detailed tutorial - style examples of how these tools were used , and point to resources for further reading on these topics . we conclude with ideas about how python promotes good scientific programing practices , and tips for scientists interested in learning more about python . .... locus        nc_001416               48502 bp     dna      linear    phg 28-nov-2007 definition   enterobacteria phage lambda , complete genome . accession    nc_001416 version      nc_001416.1   gi:9626243 project      genomeproject:14204 keywords     . source       enterobacteria phage lambda    organism   enterobacteria phage lambda              viruses ; dsdna viruses , no rna stage ; caudovirales ; siphoviridae ;              lambda - like viruses . reference    1   ( sites )    authors    chen , c.y . and richardson , j.p . title      sequence elements essential for rho - dependent transcription              termination at lambda tr1    journal    j. biol . ( 23 ) , 11292 - 11299 ( 1987 )     pubmed    3038914 ... features              location / qualifiers       source           1 .. 48502                       /organism="enterobacteria phage lambda "                       /mol_type="genomic dna "                       /specific_host="escherichia coli "                       /db_xref="taxon:10710 " gene             191 .. 736                       /gene="nu1 "                       /locus_tag="lambdap01 "                       /db_xref="geneid:2703523 "       cds              191 .. 736                       /gene="nu1 "                       /locus_tag="lambdap01 "                       /codon_start=1                       /transl_table=11 /product="dna packaging protein "                       /protein_id="np_040580.1 "                       /db_xref="gi:9626244 "                       /db_xref="geneid:2703523 "                       /translation="mevnkkqladifgasirtiqnwqeqgmpvlrgggkgnevlydsa                       avikwyaerdaeieneklrreveelrqaseadlqpgtieyerhrltraqadaqelkna                       rdsaevvetafctfvlsriageiasildglplsvqrrfpelenrhvdflkrdiikamn                       kaaaldelipgllseyieqsg " ... origin                1 gggcggcgac ctcgcgggtt ttcgctattt atgaaaattt tccggtttaa ggcgtttccg         61 ttcttcttcg tcataactta atgtttttat ttaaaatacc ctctgaaaag aaaggaaacg        121 acaggtgctg aaagcgaggc tttttggcct ctgtcgtttc ctttctctgt ttttgtccgt        181 ggaatgaaca atggaagtca acaaaaagca gctggctgac attttcggtg cgagtatccg        241 taccattcag aactggcagg aacagggaat gcccgttctg cgaggcggtg gcaagggtaa        301 tgaggtgctt tatgactctg ccgccgtcat aaaatggtat gccgaaaggg atgctgaaat        361 tgagaacgaa aagctgcgcc gggaggttga agaactgcgg caggccagcg aggcagatct        421 ccagccagga actattgagt acgaacgcca tcgacttacg cgtgcgcagg ccgacgcaca ... ....    recently we performed a comparative genomics study of the genomic dna sequences of the 74 sequenced bacteriophages that infect _ e. coli _ , _ p. aeruginosa _ , or _ l. lactis _ @xcite . bacteriophages are viruses that infect bacteria . the dna sequences of these bacteriophages contain important clues as to how the relationship with their host has shaped their evolution . each virus that we examined has a dna genome that is a long strand of four nucleotides called adenine ( a ) , threonine ( t ) , cytosine ( c ) , and guanine ( g ) . the specific sequences of a s , t s , c s and g s encode for proteins that the virus uses to take over the host bacteria and create more copies of itself . each protein is encoded in a specific region of the genomic dna called a gene . proteins are made up of linear strings of 20 amino acids . there are 4 bases encoding for 20 amino acids , and the translation table that governs the encoding , called the genetic code , is comprised of 3 base triplets called codons . each codon encodes a specific amino acid . since there are 64 possible codons , and only 20 amino acids , there is a large degeneracy in the genetic code . for more information on the genetic code , and the biological process of converting dna sequences into proteins , see @xcite . because of this degeneracy , each protein can be ` spelled ' as a sequence of codons in many possible ways . the particular sequence of codons used to spell a given protein in a gene is called the gene s ` codon usage ' . as we found in @xcite , bacteriophages genomes favor certain codon spellings of genes over the other possibilites . the primary question of our investigation was - does the observed spellings of the bacteriophage genome shed light onto the relationship between the bacteriophage and its host @xcite ?    to address this question , we examined the codon usage of the protein coding genes in these bacteriophages for any non - random patterns compared to all the possible spellings , and performed statistical tests to associate these patterns with certain aspects about the proteins . the computational requirements of this study included :    * downloading and parsing the genome files for viruses from genbank in order to get the genomic dna sequence , the gene regions and annotations : genbank @xcite is maintained by the national center of biotechnology information ( ncbi ) , and is a data wharehouse of freely available dna sequences . for each virus , we needed to obtain the genomic dna sequence , the parts of the genome that code for genes , and the annotated function of these genes . figure 1 displays this information for lambda phage , a well - studied bacteropphage that infects _ e. coli _ @xcite , in genbank format , obtained from ncbi . once these files were downloaded and stored , they were parsed for the required information . * storing the genomic information : the parsed information was stored in a custom genome python class which also included methods for retrieving the dna sequences of specific genes . * drawing random genomes to compare to the sequenced genome : for each genome , we drew random genomes according to the degeneracy rules of the genetic code so that each random genome would theoretically encode the same proteins as the sequenced genome . these genomes were then visually compared to the sequenced genome through zero - mean cumulative sum plots discussed below . * visualize the comparisons through ` genome landscape ' plots : genome landscapes are zero - mean cumulative sums , and are useful visual aids when comparing nucleotide frequency properties of the genomes they are constructed from ( see @xcite for more information ) . genome landscapes were computed for both the sequenced genome , and each drawn genome . the genome landscape of the sequenced genome was compared to the distribution of genome landscapes generated from the random genomes to detect regions of the genomes that have extremely non - random patterns in codon usage . * statistically analyzing the non - random regions with annotation and host information : to understand the observed trends , we performed analysis of variance ( anova ) @xcite analysis to detect correlations between protein function annotation or host lifestyle information with these regions . python was used in every aspect of this computational work flow . below we discuss in more detail how python was used in several of these areas specifically , and provide illustrative tutorial - style examples . for more information on the details of the computational work flow , and the biological hypotheses we tested , see @xcite . for specific details on the versions of software used in this paper , and links to free downloads , see materials and methods . biopython is an open - source suite of bioinfomatics tools for the python language @xcite . the suite is comprehensive in scope , and offers python modules and routines to parse bio - database files , facilitate the computation of alignments between biological sequences ( dna and protein ) , interact with biological web - services such as those provided by ncbi , and examine protein crystallographic data to name a few .    in this project , biopython was used both to download and parse genomic viral dna sequence files from the ncbi genbank database @xcite as outlined in listing [ genbank_code ] .    .... # genbank.py - utilities for downloading and parsing genbank files    from bio import genbank # ( 1 ) from bio import seqio    def download(accession_list ) :      ' ' ' download and save all genbank records in accession_list . ' ''           try :          handle = genbank.download_many(accession_list ) # ( 2 )      except :          print " are you connected to the internet ? "          raise           genbank_strings = handle.read().split('//\n ' ) # ( 3 )      for i in range(len(accession_list ) ) :            # save raw file as .gb gb_file_name = accession_list[i]+'.gb '                 f = open(gb_file_name,'w ' )          f.write(genbank_strings[i ] ) # ( 4 )          f.write('//\n ' )          f.close ( )     def parse(accession_list ) :      ' ' ' parse all records in accession_list . ' ''           parsed = [ ]      for accession_number in accession_list :          gb_file_name = accession_number+'.gb '          print ' parsing ... ' , accession_number          try :              gb_file = file(gb_file_name,'r ' )          except ioerror :              print ' is the file % s downloaded ? ' % gb_file_name              raise                   gb_parsed_record = seqio.parse(gb_file,"genbank").next ( ) # ( 5 )          gb_file.close ( )                   print gb_parsed_record.id   # ( 6 )          print gb_parsed_record.seq                   parsed.append(gb_parsed_record ) # ( 7 )           return parsed     import genbank # ( 8) genbank.download(['nc_001416 ' ] ) genbank.parse(['nc_001416 ' ] )     # ( 1 ) the biopython module is called bio .   the bio.genbank module is used to download records from genbank , and the bio.seqio module provides a general interface for parsing a variety of biological formats , including genbank . # ( 2 ) the bio.genbank.download\_many method is used in the genbank.download method to download genbank records over the internet . it takes a list of genbank accession numbers identifying the records to be downloaded . # ( 3 ) genbank records are separated by the character string \verb=//\n=.   here we manually separate genbank files that are part of the same character string . # ( 4 ) when we save the genbank records as individual files to disk , we include the \verb=//\n= separator again . # ( 5 ) the bio.seqio.parse method can parse a variety of formats . here we use it to parse the genbank files on our local disk using the " genbank " format parameter . the method returns a generator , who 's next ( ) method is used to retrieve an object representing the parsed file . # ( 6 ) the object representing the parsed genbank file has a variety of methods to extract the record i d and sequence . see listing \ref{genome_code } for more details . # ( 7 ) the genbank.parse method returns a listed of parsed objects , one for each input sequence file . # ( 8) to run the code in genbank.py , biopython 1.44 must first be installed ( see materials and methods ) . executing the following code should create a file called ` nc\_001416.gb ' on the local disk ( see figure \ref{lambda - genbank } ) , as well as produce the following output :    ' '' parsing ... nc_001416 nc_001416.1 seq('gggcggcgacctcgcgggttttcgctatttatgaaaattttccggtttaaggcgtttccg ... ' , iupacambiguousdna ( ) ) ' '' ....    the benefits of using biopython in this project were several including :    1 . not having to write or maintain this code ourselves . this is an important point as the number of web - available databases and services grows . these often change rapidly , and require rigorous maintenance to keep up with tweaks to api s and formats - a monumental task that is completed by an international group of volunteers for the biopython project . 2 .   the biopython parsing code can be wrapped in custom classes that make sense for a particular project . listing [ genome_code ] illustrates the latter by outlining a custom genome class used in this project to store the location of coding sequences for genes ( cds_seq ) .    .... # genome.py - a custom genome class which wraps biopython parsing code    import genbank # ( 1 ) from bio import seq from bio.alphabet import iupac    class genome(object ) :      " " " genome - representing a genomic dna sequence with genes           genome.genes[i ] returns the cds sequences for each gene i. " " "           def _ _ init__(self , accession_number ) :                   genbank.download([accession_number ] ) # ( 2 )          self.parsed_genbank = genbank.parse([accession_number])[0 ]                   self.genes = [ ]                   self._parse_genes ( )                    def _ parse_genes(self ) :          " " " parse out the cds sequence for each gene . " " "                   for feature in self.parsed\_genbank.features : # ( 3 )              if feature.type = = ' cds ' :                                   # build up a list of ( start , end ) tuples that will                  # be used to slice the sequence in self.parsed\_genbank.seq                  #                  # biopython locations are zero - based so can be directly                  # used in sequence splicing                    locations = [ ]                  if len(feature.sub_features ) : # ( 4 )                      # if there are sub\_features , then this gene is made up                      # of multiple parts .   store the start and end positins                      # for each part .                      for sf in feature.sub_features : locations.append((sf.location.start.position ,                                            sf.location.end.position ) )                  else :                      # this gene is made up of one part . store its start and                       # end position . locations.append((feature.location.start.position ,                                        feature.location.end.position ) )                     # store the joined sequence and nucleotide indices forming                  # the cds . seq = '' # ( 5 )                  for begin , end in locations :                      seq + = self.parsed_genbank.seq[begin:end].tostring ( )                    # reverse complement the sequence if the cds is on                  # the minus strand                    if feature.strand = = -1 :   # ( 6 )                    seq_obj = seq.seq(seq,iupac.ambiguous_dna )                    seq = seq_obj.reverse_complement().tostring ( )                    # append the gene sequence                  self.genes.append(seq ) # ( 7 )    # ( 1 ) here we import the genbank module outlined in listing \ref{genbank_code } , along with two more biopython modules . the bio.seq module has methods for creating dna sequence objects used later in the code , and the bio.alphabet module contains definitions for the types of sequences to be used . in particular we use the bio.alphabet.iupac definitions . # ( 2 ) we use the genbank methods to download and parse the genbank record for the input accession number . # ( 3 ) the parsed object stores the different parts of the genbank file as a list of features . each feature has a type , and in this case , we are looking for features with type ' cds ' , which stores the coding sequence of a gene . # ( 4 ) for many organisms , genes are not contiguous stretches of dna , but rather are composed of several parts .   for genbank files , this is indicated by a feature having sub\_features . here we gather the start and end positions of all sub features , and store them in a list of 2-tuples .   in the case that the gene is a contiguous piece of dna , there is only one element in this list . # ( 5 ) once the start and end positions of each piece of the gene are obtained , we use them to slice the seq of the parsed\_genbank object , and collect the concatenated sequence into a string . # ( 6 ) since dna has polarity , there is a difference between a gene that is encoded on the top , plus strand , and the bottom , minus strand . the strand that the gene is encoded in is stored in feature.strand . if the strand is the minus strand , we need to reverse compliment the sequence to get the actual coding sequence of the gene . to do this we use the bio.seq module to first build a sequence , then use the reverse\_complement ( ) method to return the reverse compliment . # ( 7 ) we store each gene as an element of the genome.genes list . the cds of the ith gene is then retrievable through genome.genes[i ] . ....    for a more detailed introduction to the plethora of biopython features , as well as introductory information into python see @xcite . matplotlib @xcite is a suite of open - source python modules that provide a framework for creating scientific plots similar to the matlab @xcite graphical tools . in this project , matplotlib was used to create genome landscape plots both to have a quick look at data as it was generated , and to produce publication quality figures . genome landscapes are cumulative sums of a zero - mean sequence of numbers , and are useful visualization tools for understanding the distribution of nucleotides across a genome ( see @xcite for more information ) . listing [ landscape_code ] outlines how matplotlib was used to quickly generate graphics to test raw simulation data as it was being generated .    .... # landscape.py - plotting a zero - mean cumulative sum of numbers    import fileinput # ( 1 ) import numpy from matplotlib import pylab    def plot(filename ) :      " " " read single - column numbers in filename and plot zero - mean cumulative sum " " "           numbers = [ ]      for line in fileinput.input(filename ) : # ( 2 )          numbers.append(float(line.split('\n')[0 ] ) )           mean = numpy.mean(numbers ) # ( 3 )      cumulative_sum = numpy.cumsum([number - mean for number in numbers ] )           pylab.plot(cumulative_sum[0::10],'k- ' ) # ( 4 )      pylab.xlabel('i ' )      pylab.title('zero mean cumulative sum ' )           pylab.savefig(filename+'.png ' ) # ( 5 )      pylab.show ( )    # ( 1 ) we use several python community modules to plot the zero - mean cumulative sum .   as part of the python standard library , fileinput can be used as a quick an easy solution to reading in a file containing a column of entries . numpy is a comprehensive python project aimed at providing numerical routines for scientific applications \cite{numpy}.   finally we import the matplotlib.pylab module which provides a matlab - like plotting environment .    # ( 2 ) here we use fileinput to read successive lines of the input file , which takes care of opening and closing the input file automatically . notice that we split each line by the newline character \verb=\n= , and take everything to the left of it , assuming that each line contains a single number . # ( 3 ) the numpy module provides many convenient methods such as mean to compute the \verb = mean= of a list of numbers , and \verb = cumsum= which computes the cumulative sum .   to shift the input numbers by the mean , we use a python list comprehension to subtract the mean from each number , and then input the shifted list to numpy.cumsum . # ( 4 ) the pylab module presents a matlab - like plotting environment . here we use several methods to create a basic line plot with an xlabel and title . # ( 5 ) to view the plot , we use pylab.show ( ) , after we have saved the figure as a png file using pylab.savefig . the following script uses the genome class outlined in listing \ref{genome_code } , along with the landscape class to plot the gc - landscape for the lambda phage genome . the genome class is used to download and parse the genbank file for lambda phage .   each gene sequence is then scanned for ' g ' or ' c ' nucleotides . for every ' g ' or ' c ' nucleotide encountered , a 1 is appended to the list gc ; for every ' a ' or ' t ' encountered , a 0 is appended . this sequence of 1 's and 0 's representing the gc - content of the lambda phage genome is saved in a file , and input into the landscape.plot method . a plot corresponding to executing this script is shown in figure \ref{lambda - landscape}.    import genome , landscape lambda_phage = genome.genome('nc_001416 ' ) gc = [ ] for gene_sequence in lambda_phage.genes :      for nucleotide in gene_sequence :          if nucleotide = = ' g ' or nucleotide = = ' c ' :              gc.append(1 )          else :              gc.append(0 )    f = file('nc_001416.gc','w ' ) for num in gc :      f.write('%i\n ' % num ) f.close ( )    landscape.plot('nc_001416.gc ' ) ....    .[lambda - landscape ] ]    matplotlib was also used to make custom graphics classes for creating publication - quality plots . to do this , we used the object oriented interface to matplotlib plotting routines to inherit funcionality in our classes . the benefits of using matplotlib in this project were several :    1 . the code that produced the scientific plots resided alongside the code that produced the underlying data for the plots . the importance of this can not be stressed enough as having the code structured in this way removed many opportunities for human error involved in manually shuffling raw data files into separate graphical programs . moreover , the instructions for producing the plots from the underlying raw data was _ python code _ , which not only described these instructions , but could be executed to produce the plots . imagine instead the often practiced use of spreadsheets to create plots from raw data - in these spreadsheets , formulas are hidden by the results of the calculations , and it is often very confusing to construct a picture of the computational flow used to produce a specific plot . 2 .   having the graphics instructions in code allowed for quick trouble shooting when creating the plots , or evaluating raw data as it was generated . complicated plots were easily regenerated by tweaking the code for particular graphical plots . the simple wrapper and interface generator ( swig ) @xcite , is an easy - to - use system for extending python . in particular , it allows the speed up of selected parts of an application by writing these routines in another more low - level language such as c or c++ . furthermore , swig implements the use of this low - level code using the standard python module importing structure . this allows developers to first prototype code in python , then re - implement the code in c and swig causing _ no change _ in the python code that uses the re - implemented module . this project relied heavily on drawing random numbers from an input discrete distribution . for example , we often needed to draw a sequence of a s , t s , c s or g s corresponding to the nucleotide sequence of the genome , but preserving the genomic distribution of these four nucleotide bases . for some viruses , the distribution might look like : @xmath0 , @xmath1 , @xmath2 , @xmath3 , with @xmath4 . listing [ random_python_code ] illustrates the outline of a python module that has methods to draw numbers according to a discrete distribution with 4 possible outcomes . it also illustrates how this module could be implemented in c , and included in a python module with swig . .... # module discrete\_distribution.py - drawing numbers from a discrete probability distribution    import random # ( 1 )    def seed ( ) : # ( 2 )      random.seed ( )       def draw(distribution ) : # ( 3 )    ' ' ' drawing an index according to distribution . distribution is a list of floating point numbers ,    one for each index number , representing the probability     of drawing that index number . example : [ 0.5 , 0.5 ] would represent equal probabilities    of returning a 0 or 1 .    ' ''    sum = 0 # ( 4 )    r = random.random ( )    for i in range(0,len(distribution ) ) :        sum + = distribution[i ]        if r < sum :            return i     import discrete_distribution # ( 5 ) discrete_distribution.seed ( ) print sum([discrete_distribution.draw([0.2,0.2,0.3,0.3 ] ) for x in range(10000)])/10000 . # ( 1 ) import the random number generator . # ( 2 ) we use the discrete\_distribution.seed ( ) method to seed the random number generator .   if no arguments are supplied to random.seed ( ) , the system time is used to seed the number generator \cite{python - random}.    # ( 3 ) the draw function takes an argument distribution , which is a list of floating point numbers . # ( 4 ) the algorithm for drawing a number according to a discrete distribution is to draw a number , r , from a uniform distribution on [ 0,1 ] ; compute a cumulative sum of the probabilities in the discrete distribution for successive indices of the distribution ; when r is less than this cumulative sum , return the index that the cumulative sum is at . # ( 5 ) to test this code , plug in a distribution [ 0.2,0.2,0.3,0.3 ] , draw 10000 numbers from this distribution , and compute the mean , which theoretically should be $ 0 * 0.2 + 1 * 0.2 + 2 * 0.3 + 3 * 0.3 = 1.7$.   in this case , when this code was executed , the result $ 1.7013 $ was returned . ....    in listing [ random_c_code ] , we implement this routine using c , and use swig to create a python module of the c implementation . ....    //c\_discrete\_distribution.c - a c implementation of the discrete\_distribution.py module    # include " stdlib.h " // ( 1 ) # include " stdio.h " # include " time.h "    void seed ( ) {      srand((unsigned ) time(null ) * getpid ( ) ) ;   }    int draw(float distribution[4 ] ) { // ( 2 )      float r= ( ( float ) rand ( ) / ( float ) rand_max ) ;      float sum = 0 . ;      int i = 0 ;      for(i = 0 ; i < 4 ; i++ ) {          sum + = distribution[i ] ;    if ( r lt sum ) {              return i ;    }      } }    // ( 1 ) here we define two functions , seed and draw , which correspond to the python methods in discrete\_distribution.py .   note that the python implementation of discrete\_distribution.draw ( ) worked with distributions of arbitrary numbers of elements . for simplicity , we are restricting the c implementation to work with distributions of length 4 .    // ( 2 ) the draw routine is implemented using the same algorithm as in the python implementation .   for simplicity , we use the c standard library rand ( ) routine , although there are more advanced random number generators that would be more appropriate for scientific applications \cite{random}. ( note that the ` lt ' symbol should be replaced by ` < ' when executing the code . )    // c\_discrete\_distribution.i - a swig interface file for the c\_discrete\_distribution module // ( 3 )    % module c_discrete_distribution // ( 4 )    // grab a 4 element array as a python 4-list // ( 5 ) % typemap(in ) float[4](float temp[4 ] ) {    // temp[4 ] becomes a local variable    int i ;    if ( pylist_check($input ) ) {      pyobject * input_to_tuple = pylist_astuple($input ) ;      if ( ! pyarg_parsetuple(input_to_tuple,"ffff",temp , temp+1,temp+2,temp+3 ) ) {        pyerr_setstring(pyexc_typeerror,"tuple must have 4 elements " ) ;        return null ;      }      $ 1 = & temp[0 ] ;    } else {      pyerr_setstring(pyexc_typeerror,"expected a tuple . " ) ;      return null ;    } }    void seed ( ) ; // ( 6 ) int draw(float distribution[4 ] ) ;      // ( 3 ) to use swig , we create a swig interface file that describes how to translate python inputs to the c code , and c outputs to the python code .    // ( 4 ) swig directives are preceded by the \% sign . here we declare that the module we are going to make is called c\_discrete\_distribution .   in general , the module name , the c source name , and the interface file name should all be the same outside of the file extension .    // ( 5 ) swig will automatically handle the conversion of many data - types from python to c and c to python .   for illustration purposes , we create an explicit typemap which converts a 4-element python list into a 4 element c list of floats . since we are using the typemap(in ) directive , swig knows that we are converting python to c.   the rest of the code checks that a list was passed from python to c , and the list has 4 elements . if these conditions are not met , python errors are thrown . if they are met , an array of floats called temp is called , and passed to c.   this conversion is adapted from the swig reference manual \cite{swig}.    // ( 6 ) the last thing to do in the swig interface file is to declare the function signatures of the c implementation . ....    to use this module outlined in listing [ random_c_code ] , we have to call swig to generate wrapper code , then compile and link our code with the wrapper code . with swig installed , the procedure would look something like    .... swig -python -o c_discrete_distribution_wrap.c c_discrete_distribution.i ....    we first use swig to generate the wrapper code . using the c_discrete_distribution.i interface file , swig will generate c_discrete_distribution_wrap.c using the python c api , since we specified the -python flag . in addition , swig will also generate c_discrete_distribution.py , which we will use to import the module into our code . .... gcc -c c_discrete_distribution.c c_discrete_distribution_wrap.c      -i / usr / include / python2.5 -i / usr / lib / python2.5 ....    next we use a c compiler to compile each of the c files ( our c source , and the swig generated wrapper ) . we have to include the python header files and libraries for the python version we are using . in our case , we used python 2.5 . after this procedure completes , we should have two additional files : c_discrete_distribution.o and c_discrete_distribution_wrap.o . .... gcc -bundle -flat_namespace -undefined suppress -o _ c_discrete_distribution.so c_discrete_distribution.o c_discrete_distribution_wrap.o ....    the final step is to link them all together . the linking options are platform dependent , and the official swig documentation should be consulted @xcite . for mac os x , we use the `` -bundle -flat_namespace -undefined suppress '' options for gcc . when this step is done , the file _ c_discrete_distribution.so is created . the python module file c_discrete_distribution.py can be used in the same way as in listing [ random_python_code ] above ,    .... import c_discrete_distribution as discrete_distribution discrete_distribution.seed ( ) print sum([discrete_distribution.draw([0.2,0.2,0.3,0.3 ] ) for x in range(10000)])/10000 .   ....    which produces the number 1.6942 . the benefits of using swig in this project were several :    1 . we used all the benefits of python with the increased speed for critical bottlenecks of our simulation code . the parts that were sped up were used in the exact same context through the python module import structure , removing the need for glue code to tie in external c - programs . more generally , swig allows scientists using python to leverage experience in other languages that they typically have , while staying within the python framework with all its benefits outlined above . this promotes a scientific work flow which consists of prototyping simulation code using the more simple python , then profiling the python code to identify the speed bottlenecks . these can then be re - implemented in c or c++ and wrapped into the existing python code using swig . this is a much preferred methodology than writing unnecessarily complicated and error - prone c programs , and using glue code to integrate them within the larger simulation methodology . there are several practical conclusions to draw for scientists . the first is that python , and its associated modules supported by the python community , offer a general platform for computing that is useful accross a broad range of scientific disciplines . we have only outlined several such tools in this article , but there exist many more relevant to scientists @xcite . the second is that python and its community modules can _ easily _ be used by scientists . the clean nature of the code is quick to learn , and its high - level features make complicated tasks quick to accomplish . we have not discussed the interactive programming environments offered by python@xcite , which when combined with the power of the language makes prototyping ideas and algorithms extremely easy . the bigger picture conclusion is that python promotes good scientific practice . the code readability and package structure enables code to be easily understood by different researchers working on the same project . in fact , python code is often self - documenting which allows researchers to go back to code they wrote in the past and easily understand it . python and its community modules provide a consistent framework to generate data , and shuttle it to the various analysis tasks . this in turn promotes data provenance through a written record _ in code _ of every step used to analyze specific data , which removes many manual steps , and thus many errors .    finally , by using python , scientists can start to use other community tools and practices originally designed for professional programmers , but also useful to scientists . the most important of these , but not discussed in this article , is unit testing , whereby test code is written alongside scientific code that tests to see if that code is working properly . this allows scientists to re - write aspects of the code , perhaps using a different algorithm , and to re - run the tests to see if it still works as they think it should . for large projects this is critical , and removes the need for often - used ad - hoc practices of looking at some sample data by eye , which is not only tedious , but not guaranteed to uncover subtle numerical bugs that could cause crucial mis - interpretation of scientific data .    since python is a well - established language and has a large and active community , the resources available for beginners can be overwhelming . for the scientist interested in learning more about scientific programming in python , we recommend visiting the web page and mailing lists of the scipy project for an introduction to scientific modules @xcite , and @xcite for excellent introductory python tutorials . all code examples in this paper were written by the author . the particular versions of the relevant software used were : python 2.5 , biopython 1.44 , matplotlib 0.91.2 , and swig 1.3.33 . documentation and free downloads of this software are available at the following urls :    * python - http://python.org * biopython - http://biopython.org * matplotlib - http://matplotlib.sourceforge.net * swig - http://www.swig.org/    the source code for all the listings above , as well as the original and maintained version of this article can be found at ` http://openwetware.org/wiki/julius_b._lucks/projects/python_all_a_scientist_needs ` . the author would like to thank adrian del maestro , joao xavier , david thompson and stanley qi for helpful comments during the preparation of this manuscript . the author also thanks the miller institute for basic research in science at the university of california , berkeley for support . 10    j. b. lucks , d. r. nelson , g. kudla , j. b. plotkin . _ genome landscapes and bacteriophage codon usage _ , plos computational biology , * 4 * , .1000001 , 2008 . ( http://dx.doi.org/10.1371/journal.pcbi.1000001[doi:10.1371/journal.pcbi.1000001 ] )                                                f. perez and b. granger . _ ipython : a system for interactive scientific computing _  , computing in science and engineering , 2007 .
Abstract:

Answer: any cutting - edge scientific research project requires a myriad of computational tools for data generation , management , analysis and visualization . python is a flexible and extensible scientific programming platform that offered the perfect solution in our recent comparative genomics investigation @xcite . in this paper , we discuss the challenges of this project , and how the combined power of biopython @xcite , matplotlib @xcite and swig @xcite were utilized for the required computational tasks . we finish by discussing how python goes beyond being a convenient programming language , and promotes good scientific practice by enabling clean code , integration with professional programming techniques such as unit testing , and strong data provenance .


Instruction: Write an abstract for the following acadamic paper.

Input:
Paper: we have recorded the flight of a fly during take off and landing using digital high speed photography . it is shown that the dynamics of flexible wings are different for these procedures . during this observation fly flew freely in a big box and it was not tethered .
Abstract: in this fluid dynamics video , we demonstrated take off and landing of a fly . the deformation of wings is in focus in this video .

Paper: several resonant - mass gravitational wave antennas are now in continuous operation with strain sensitivities of the order @xmath0 @xcite . with further improvements to these detectors and the addition of several large laser interferometers now under construction @xcite , the prospects for gravitational wave astronomy are quite good . the underlying non - gravitational physics associated with these detectors is reasonably understood and further improvements can be based on solid technological guidelines .    many believe the next generation of resonant - mass antennas will be of spherical shape @xcite . confirmed detection of gravitational waves will require a coincidence between several detectors , thus the unique features of a sphere may play an essential role in a network of gravitational wave antennas . two important features of a sphere are its equal sensitivity to gravitational waves from all directions and polarizations and its ability to determine the directional information and tensorial character of a gravitational wave @xcite .    to take full advantage of these capabilities , one needs to be able to interpret the data such a detector will produce . recently , much work has been done to understand the output of a spherical antenna equipped with resonant transducers @xcite . all of these proposals operate on the principle that the response of the transducers can be transformed into a quantity that has a one - to - one correspondence with the tensorial components of a gravitational wave . with the measurement of these components , it is possible to solve the inverse problem to obtain the direction and polarization amplitudes of a gravitational wave . the solution to the inverse problem for a noiseless spherical antenna first was outlined in the mid 1970 s by wagoner and paik @xcite . more recently , the solution for a network of five noiseless bar antennas or interferometers was solved by dhurandhar and tinto @xcite . this method assumed that the detectors were co - located but oriented in different directions . this solution is quite elegant because the exact solution can be found using straightforward algebra . since a sphere can be thought of as five bar detectors occupying the same space , this solution can be adapted for a spherical antenna @xcite . in addition , lobo outlined a procedure that can be used if the correct theory of gravity is not general relativity but unknown @xcite . what all these proposals have in common is that they use basic symmetry properties of the matrices describing the detectors and their response to a gravitational wave . this makes them intuitive and easy to visualize @xcite . the solution to the inverse problem in the presence of noise is more complicated . grsel and tinto solved the problem for three noisy interferometers using a maximum likelihood method @xcite . this solution required the measurement of the time delay of the signal between widely separated detectors to triangulate the direction of the source . zhou and michelson showed that the inverse problem for a spherical antenna can be solved in the presence of noise , also using a maximum likelihood method @xcite . what is disappointing about the maximum likelihood method is that the original simplicity of dhurandhar and tinto s noiseless solution is lost . in addition , an exact solution for the spherical detector was not found , making it necessary to solve the problem numerically . this solution can be computationally expensive , especially if the signal - to - noise ratio ( snr ) is low . for the three interferometer case , the numerical solution often can lead to an incorrect estimate at low snr @xcite . this appears not to be a problem for a spherical antenna ; a global maximum usually exists and is aligned with the correct direction . this leads us to believe that the problem for a spherical antenna can be solved analytically .    on experiments with the room - temperature prototype spherical antenna ( tiga ) at louisiana state university , we used a procedure to solve the inverse problem for impulsive excitations applied to the sphere surface @xcite . this solution was similar to dhurandhar and tinto s original solution for gravitational waves , but we used a perturbation argument ( presented below ) to take into account the finite snr of the experiment . the case of an impulsive excitation is more simple than a gravity wave because fewer parameters are involved , however , we show below that this method also can be used to find an analytic solution for gravitational waves . we begin by reviewing the response of a spherical antenna to gravitational waves in general relativity and show how dhurandhar and tinto s original method can be applied to solve for the wave direction and polarization amplitudes . we then generalize the arguments to any symmetric metric theory of gravity as well as to impulsive excitations . in sec . [ sec : noisy ] we show how this technique can be extended to a noisy antenna with independent and equally sensitive detector outputs . this solution is found to be equivalent to the maximum likelihood method under the same noise requirements . the general approach taken allow this solution to be easily adapted to other types of excitations with similar symmetry properties . we conclude the paper with a discussion of the limitations of the solution and possible extensions of this method . dhurandhar and tinto solved the inverse problem for 5 bar antennas as well as 5 interferometers @xcite . others have used their method to solve the problem for a spherical antenna @xcite . their technique involves constructing a matrix , say @xmath1 , that describes the response of the detector to a gravitational wave . they found that in general relativity the eigenvector of @xmath1 with zero eigenvalue points in the propagation direction of the wave . in the following we will also use this concept , but will derive the equations in the context of linear algebra as this will lead us directly into the solution for the noisy antenna . for a more complete discussion of the response of an elastic sphere to gravitational waves the reader is referred to refs . @xcite . a gravitational wave is a traveling time - dependent deviation of the metric perturbation , denoted by @xmath2 . we follow a common textbook development for the metric deviation of a gravitational wave , which finds that only the spatial components @xmath3 are non - zero , and further can be taken to be transverse and traceless @xcite . this tensor is simplified if we initially write it in the `` wave - frame , '' denoted by primed coordinates and indices . this is a coordinate frame with origin at the center of mass of the detector and the @xmath4 axis aligned to the propagation direction of the wave . we restrict ourselves to detectors much smaller than the gravitational wavelength so only the time dependence of @xmath3 will have significant physical effects . a general form for the spatial components of the metric deviation in the wave - frame can be written as @xmath5 ,     \label{eqn : wave_strain}\ ] ] where @xmath6 and @xmath7 are the wave amplitudes for the two allowed states of linear polarization and are called the plus and cross amplitudes . the detector is more easily described in the `` lab - frame , '' denoted by unprimed coordinates and indices , with origin at the center of mass of the detector and the @xmath8 axis aligned with the local vertical . in this frame , the primary physical effect of a passing gravitational wave is to produce a time dependent `` tidal '' force density @xmath9 on the material with mass density @xmath10 at coordinate location @xmath11 . this force is related to the metric perturbation by @xmath12    it is natural to look for an alternate expression that separates the coordinate dependence into radial and angular parts . because the tensor @xmath3 is traceless , the angular expansion can be done completely with the five second order real valued spherical harmonics @xmath13 , where the index @xmath14 . we call the resulting time dependent expansion coefficients , denoted by @xmath15 , the `` spherical amplitudes '' @xcite . they are a complete and orthogonal representation of the cartesian metric deviation tensor @xmath3 . they depend only on the two wave - frame amplitudes and the direction of propagation .    to transform the metric perturbation to the lab - frame we perform the appropriate rotations using the y - convention of the euler angles shown in fig . [ fig : y - convention ] . we denote the rotation about the wave @xmath4 axis by @xmath16 , the rotation about the new @xmath17 axis ( @xmath18 ) by @xmath19 , and the rotation about the final lab @xmath8 axis by @xmath20 . the rotation matrix for the y - convention is @xmath21 . \label{eqn : rotation_matrix_full}\ ] ] at this point we arbitrarily set the rotation @xmath16 about the wave @xmath4 axis equal to zero ; inclusion of this rotation will only `` mix '' the two polarizations of the wave . the spherical amplitudes can now be written in terms of the polarization amplitudes and the source direction    [ eqn : h_all ] @xmath22    the mechanics of a spherical antenna can be described by ordinary elastic theory . one finds that the eigenfunctions of an uncoupled sphere can be written in terms of the spherical harmonics @xmath23 the radial eigenfunctions @xmath24 and @xmath25 determine the motion in the radial and tangential directions respectively and depend on the radius @xmath26 and the material of the sphere @xcite .    in general relativity , only the 5 quadrupole modes of vibration will strongly couple to the force density of a gravitational wave . for an ideal sphere they are all degenerate , having the same eigenfrequency , and are distinguished only by their angular dependence . the effective force @xmath27 that a gravitational wave will exert on a fundamental quadrupole mode  @xmath28 of the sphere is given by the overlap integral between the eigenfunctions of the sphere and the gravitational tidal force @xmath29 each spherical component of the gravitational field determines uniquely the effective force on the corresponding mode of the sphere and they are all identical in magnitude . we can interpret the effective force @xmath27 in each mode as the product of : the physical mass of the sphere @xmath30 , an effective length @xmath31 ( a fraction of the sphere radius ) , and the gravitational acceleration @xmath32 . the value of the coefficient @xmath33 depends on the sphere material , but is typically @xmath34 @xcite .    by monitoring the quadrupole modes of the sphere , one has a direct measurement of the effective force on the sphere and thus the spherical amplitudes of the gravitational wave . the standard technique for doing so on resonant detectors is to position resonant transducers on the surface of the sphere that strongly couple to the quadrupole modes . a number of proposals have been made for the type and positions of the transducers @xcite . what all of these proposals have in common is that the outputs of the transducers are combined into `` mode channels '' @xmath35 that are constructed to have a one - to - one correspondence with the quadrupole modes of the sphere and thus the spherical amplitudes of the gravitational wave @xcite , @xmath36 the mode channels can be collected to form a `` detector response '' matrix @xmath37 that in the absence of noise is equal to the cartesian strain tensor @xmath38 in the lab frame @xmath39 . \label{eqn : cartesian_strain_tensor}\ ] ] for the remainder of this discussion we drop the notation of time dependence @xmath40 for brevity . the strain tensor in the lab frame @xmath41 is a symmetric traceless matrix . consequently , it can be orthogonally diagonalized and has an orthonormal set of three eigenvectors . one can construct from the eigenvectors a transformation matrix @xmath42 that diagonalizes @xmath41 . the matrix @xmath42 is also orthogonal , thus it can be considered a rotation matrix ( it may also include a reflection ) . the physical interpretation of this transformation is to rotate the lab frame such that the @xmath8 axis points in the direction of the source . the matrix @xmath42 ( the eigenvectors ) will tell us the angles of rotation and thus the direction of the wave .    in the wave frame , @xmath43 is not normally diagonal but it can be diagonalized by rotating eq .  ( [ eqn : wave_strain ] ) about the propagation axes using the euler angle @xmath16 . @xmath16 may be a constant or a function of time depending upon the situation . this rotation changes the polarization components of the tensor but not the wave direction relative to the lab frame . to calculate the rotation matrix @xmath42 we need to solve the general eigenvalue equation for the strain tensor @xmath44 since @xmath1 and @xmath41 are equal in the absence of noise we are free to substitute @xmath1 in eq . ( [ eqn : general_strain_ev ] ) for @xmath41 . by inspection of eq . ( [ eqn : wave_strain ] ) we see that in general relativity the eigenvector of @xmath41 with @xmath45 points in the propagation direction of the wave . the direction can be calculated from this eigenvector by recognizing that it corresponds to the last column vector of @xmath42 in eq . ( [ eqn : rotation_matrix_full ] ) . dividing the elements of this column we find @xmath46 @xmath47 the unusual minus sign in eq . ( [ eqn : gamma ] ) comes from the use of the y - convention of the euler angles . expanding eq . ( [ eqn : general_strain_ev ] ) for @xmath45 and substituting in a particular choice of matrix elements from eq . ( [ eqn : cartesian_strain_tensor ] ) we find @xmath48 @xmath49    this solution is valid only for a noiseless antenna ; it will fail otherwise because we can no longer replace @xmath41 with @xmath1 and their eigenvectors and eigenvalues will no longer be equal . the @xmath50 in eq . ( [ eqn : noisless_beta ] ) illustrates the unavoidable fact that a single sphere can not distinguish between antipodal sources . this ambiguity is a characteristic of all gravity wave detectors , but can be removed by measuring the time delay of the signal between two widely separated antennas . once the direction is calculated we can determine the two polarization amplitudes by taking a linear combination of eqs . ( [ eqn : h_all ] ) . these equations are actually overdetermined so several solutions exist ( we have 5 equations but only 4 unknowns ) . in the absence of noise any particular solution to them is valid , but in anticipation of the noisy case we will take a systematic approach to the solution .    we need only the angles @xmath19 and @xmath20 to rotate @xmath41 to @xmath43 , so at this point we again set @xmath51 . the amplitudes are found by equating them to the corresponding matrix elements of @xmath43 in eq . ( [ eqn : wave_strain ] ) . again , we may substitute @xmath1 for @xmath41 and @xmath52 for @xmath43 so we have @xmath53 and @xmath54 . @xmath1 and @xmath52 are symmetric so @xmath55 and @xmath56 will always be identical even when noise is introduced . however , no such restriction is placed on @xmath57 and @xmath58 . we will use the average @xmath59 to calculate @xmath60 for reasons that will become clear later . multiplying @xmath61 for @xmath51 and selecting the proper elements we find @xmath62 @xmath63 these equations can also be derived by taking a linear combination of eqs . ( [ eqn : h_all ] ) . this is not the only valid solution in the noiseless case , but it is particularly symmetric : the coefficients of each component @xmath64 is the same as the corresponding coefficients of @xmath60 or @xmath65 in eqs . ( [ eqn : h_all ] ) for @xmath66 . the fact that @xmath65 does not contain a @xmath67 contribution is an artifact of using the y - convention of the euler angles ; in other conventions this term may be non - zero . experiments in the solar system and pulsar - timing tests have ruled out many competing theories of gravity , however , general relativity is not the only theory of gravity that passes these weak field tests @xcite . one measurement that can potentially rule out certain gravitational theories is the properties of gravitational waves @xcite , such as the speed of propagation and allowable polarization states . it was shown above how a single sphere can measure the quadrupole components of the strain tensor , but a scalar wave can excite both the monopole mode and the quadrupole modes of a sphere @xcite . by monitoring both types of modes , a single spherical detector can measure all the tensor components of a gravitational wave . this makes it possible for a single spherical detector to determine all of the six polarization states predicted by the most general symmetric metric theory of gravity @xcite . we can rewrite eq . ( [ eqn : eff_force ] ) in terms of the electric components of the riemann tensor @xcite @xmath68 , @xmath69 where we now include both the @xmath70 quadrupole modes and the @xmath71 monopole mode . the monopole mode of an elastic sphere is actually at a higher frequency than the quadrupole modes . if the source is not wide - band enough for detection in both of these modes , a second sphere with the monopole mode tuned to the quadrupole modes of the first will be needed to measure this component . if the first sphere is at relatively low frequency , one might consider making the second sphere hollow to keep it of a practical size @xcite . an alternative to a second sphere is to monitor the @xmath72 quadrupole modes and the monopole mode of a single sphere . these modes are not far in frequency from each other and also have relatively large cross - sections @xcite . expanding eq . ( [ eq : electric_force ] ) into radial and angular parts we find an additional spherical amplitude @xmath73 corresponding to the @xmath71 spherical harmonic . the detector response in the lab frame can now be written as @xmath74 . \label{eq : general_response}\ ] ]    to determine how to solve the inverse problem we need to examine the form of @xmath75 . it is a symmetric tensor so it has only six independent components . it can be written in terms of the complex newman - penrose parameters @xcite which allow the identification of the spin content of the metric theory responsible for the generation of the wave @xmath76.\ ] ]    we can divide the theories of gravity into categories using the e(2 ) classification scheme shown in tab . [ tab : e2_class ] @xcite . the tensor @xmath75 is symmetric for all of these classes , thus it is orthogonally diagonalizable , but classes @xmath77 and @xmath78 have more degrees of freedom ( direction plus polarization states ) than we are capable of measuring with a single spherical detector . these two classes are often referred to as `` observer - dependent '' because different observers will disagree upon which polarization states are present . as a consequence , the polarization amplitudes for a particular observer must be known before the direction of the wave can be estimated .    for the `` observer - independent '' classes @xmath79 , @xmath80 , @xmath81 , and @xmath82 , the situation is more straightforward . @xmath79 is obviously uninteresting as it does not predict any gravitational waves ( this class along with @xmath80 have essentially been ruled out by previous experiments @xcite ) . we notice that @xmath75 for the observer - independent classes can be diagonalized by a rotation @xmath16 about the propagation axis , therefore , we can use the same arguments presented above for general relativity to solve for the wave direction . the most general observer - independent class is @xmath82 , which has @xmath83.\ ] ] looking at the form of @xmath75 we see that the same procedure for calculating the direction of the wave in general relativity holds for all the observer - independent classes : the eigenvector of @xmath1 with eigenvalue equal to zero points at the source . the one exception to this statement is the case where the driving forces remain in a fixed line , for example @xmath84 . in this situation the direction of the wave can only be determined within the plane defined by the two eigenvectors with eigenvalues equal to zero . impulsive excitations are often used on resonant - mass detectors to calibrate the antenna @xcite . the excitations are usually administered by either a short electrical burst applied to a calibrator attached to the surface or a hammer blow . impulsive excitations were also used to test the analysis techniques used for experiments with the prototype spherical antenna at louisiana state university @xcite . a radial impulse excitation can be easily described if we choose the @xmath4 axis to be along the direction of the impulse . by examining the quadrupole eigenfunctions of the sphere in this frame we notice that out of these modes only the @xmath85 mode will be excited ( other sphere modes will also be excited but their response can be removed by narrow - band filtering ) . all of the other quadrupole modes have a vanishing radial component of their eigenfunctions at this location which makes their `` overlap '' integral with the impulse vanish . in this frame the detector response is @xmath86 . \label{eqn : impulse_matrix}\ ] ] in the lab frame @xmath1 is still given by eq . ( [ eqn : cartesian_strain_tensor ] ) . again , the direction can be found by calculating the eigenvalues and eigenvectors of the lab frame @xmath1 . in the absence of noise , the eigenvector corresponding to the direction has a non - zero eigenvalue that is opposite in sign and twice as large as the two other eigenvalues . we now return to the case of a gravitational wave in general relativity to solve the inverse problem in the presence of noise . at the end of this section we present the application of this solution to the other types of excitations mentioned above . for this discussion we assume that the mode channels @xmath87 are independent and have normally distributed noise with the same variance . this is a reasonable assumption as the truncated icosahedral arrangement of identical transducers ideally satisfies these conditions @xcite . in addition , several other proposals of transducer arrangements also produce independent mode channels @xcite ( but the sensitivity of each mode channel is different under normal conditions @xcite ) . noise in the mode channels @xmath87 will change the eigenvalues and eigenvectors of @xmath1 such that they are no longer equal to those of @xmath41 . to gain some insight into this situation , let us consider the noise as a perturbation @xmath88 to the matrix @xmath41 @xmath89 the matrix @xmath88 is constructed from the noise in each mode channel @xmath87 , thus it has the same form as eq . ( [ eqn : cartesian_strain_tensor ] ) . the matrix @xmath1 is therefore still symmetric and traceless and has the eigenvalue equation @xmath90 the eigenvectors of @xmath41 can be expanded in terms of the eigenvectors of @xmath1 @xmath91 where the matrix @xmath92 is close to the identity matrix if the perturbation is small . however , since we do not know the values of the matrix @xmath88 we can not calculate any corrections to the matrix elements @xmath93 , thus the best approximation to @xmath94 we can find is @xmath95 .    also from perturbation theory we see that the eigenvalue corresponding to the estimated direction of the wave is @xmath96 if the perturbation is small . its magnitude will increase as the snr decreases , but it should remain smaller than the other two eigenvalues of @xmath1 for snr @xmath97 . consequently the eigenvector corresponding to the estimated direction of the wave can be selected from the three eigenvectors of @xmath1 by choosing the one whose eigenvalue is `` closest '' to zero . once @xmath95 is found , it can be used to estimate the direction of the source using eqs . ( [ eqn : gamma ] ) and  ( [ eqn : beta ] ) . the perturbation approach gives us a conceptual feel for the solution , but a more rigorous proof seems necessary . the problem we wish to solve is to estimate the direction and polarization that makes the measured five mode channels @xmath98 most `` look like '' the expected signal from a gravitational wave , @xmath99 from eqs . ( [ eqn : h_all ] ) . zhou and michelson used a statistical argument to justify using the least square error in their maximum likelihood method to fit for the direction and polarization @xcite . given the poor statistics in this estimation ( only five samples ) one might question their statistical approach , nevertheless the least squares error seems to be a reasonable choice to make under the conditions on the noise stated above . the least squares error can be written as @xmath100 the values of @xmath101 and @xmath102 that minimize @xmath103 can be found by simultaneously solving the equations @xmath104 and @xmath105 . doing so using eqs . ( [ eqn : h_all ] ) we find @xmath106 @xmath107 note that eqs . ( [ eqn : h_p_ls ] ) and  ( [ eqn : h_x_ls ] ) are identical to eqs . ( [ eqn : h_p ] ) and  ( [ eqn : h_x ] ) found for the noiseless case . this connection will be useful below . we might also look for the minimum of @xmath103 with respect to the direction of the wave by taking partial derivatives with respect to @xmath19 and @xmath20 . this procedure leads to very complicated non - linear equations whose solution is not easily obtained . for this reason we instead will look at how @xmath103 varies close to our eigenvector solution . we begin by rewriting @xmath103 in terms of the detector response @xmath108 @xmath109          \left[\bbox{a}-\bbox{h}\right]^{t}\right)\ ] ] @xmath110 the inner product @xmath111 can be interpreted as the distance between @xmath1 and @xmath41 which we know to be invariant to rotations . if @xmath42 is the matrix that diagonalizes @xmath41 such that @xmath112 , we can write @xmath113 it is now clear that the least squares fit is the matrix @xmath42 that minimizes the distance @xmath103 . geometrically , this minimum occurs when @xmath114 is the projection of @xmath43 onto @xmath1 . given that @xmath43 is diagonal one might guess that this minimum occurs when @xmath52 is also diagonal . let us proceed to prove this conjecture . let @xmath115 be the matrix constructed from the eigenvectors of @xmath1 so that @xmath116 where @xmath117 is a diagonal matrix . let us also assume @xmath115 differs from @xmath42 by a small rotation @xmath118 such that @xmath119 ,      \label{eq : r}\ ] ] where @xmath120 is a skew - symmetric matrix with zeros along the diagonal . substituting eq . ( [ eq : r ] ) into eq . ( [ eq : ls_diag ] ) and keeping terms only up to @xmath121 we find @xmath122      + \frac{1}{2}\epsilon^{2 }      [ \bbox{d}\bbox{w}^{2 }      -2\bbox{w}\bbox{d}\bbox{w }      + \bbox{w}^{2}\bbox{d } ]      \|^{2 } ,      \label{eq : ls_e2}\ ] ] expanding eq . ( [ eq : ls_e2 ] ) and remembering that the trace is invariant under cyclic permutations of the matrices in a product and that @xmath123 we find @xmath124 all the first order terms in @xmath125 have vanished so we have proven that @xmath103 is stationary near @xmath126 . to show this point is a minimum we need to evaluate the second order terms in @xmath125 . @xmath120 can be written in terms of a unit vector @xmath127 representing the axis of rotation , so the square of this matrix is given by @xmath128_{ij } = n_{i}n_{j } - \delta_{ij}.      \label{eq : w2}\ ] ] recalling the procedure for deriving eqs . ( [ eqn : h_p ] ) and  ( [ eqn : h_x ] ) in the noiseless case and that they are identical to the least squares minimum eqs . ( [ eqn : h_p_ls ] ) and  ( [ eqn : h_x_ls ] ) we can set @xmath129 the matrix @xmath117 is also traceless so @xmath130 . now the second order terms can be written as @xmath131 using @xmath132 and @xmath133 we find that @xmath134 is not guaranteed to be positive for all possible real values of @xmath135 and @xmath136 . fortunately we may also assume we have ordered the eigenvalues of @xmath1 such that @xmath137 is the eigenvalue closest to zero . now we have an additional condition @xmath138 , where @xmath139 . substituting this into eq . ( [ eq : oe2 ] ) we find @xmath140 by inspection we see that @xmath134 is always positive under the conditions stated above , therefore @xmath103 is always a minimum near @xmath126 . we further used a monte carlo type simulation to show that this point is always the global minimum of @xmath103 . for a wave of a given direction and polarization we calculated the spherical amplitudes @xmath99 and added a random number ( variance @xmath141 and zero mean ) to obtain the mode channels the direction and polarization were estimated using the eigenvector method as well as by numerically finding the minimum of @xmath103 from eq . ( [ eq : ls ] ) . we found the two methods gave identical results , even for high values of @xmath141 , confirming that @xmath126 is a global minimum of @xmath103 . therefore , the diagonal form of @xmath1 is the best approximation to @xmath43 and can be used to estimate the direction and polarization of the wave . both the maximum likelihood method and the eigenvector solution minimize the mean square error under the conditions on the noise stated above , therefore , produce the same answer for the estimated values . however , the eigenvector solution is more straightforward and computationally simple . we construct the matrix @xmath1 from the mode channels @xmath87 and compute its eigenvalues @xmath142 and eigenvectors @xmath95 . we choose the eigenvector with eigenvalue closest to zero and estimate the direction of the wave using eqs . ( [ eqn : gamma ] ) and  ( [ eqn : beta ] ) . the polarization amplitudes can be estimated using eqs . ( [ eqn : h_p_ls ] ) and  ( [ eqn : h_x_ls ] ) .      the detector response matrix @xmath1 for other metric theories of gravity as well as for impulse excitations satisfy the symmetry arguments used in the discussion for general relativity . this means we can easily adapt the noiseless solutions to the case where noise is present in the same fashion .    for observer - independent gravitational theories the method for estimating the direction of the wave is identical to that of general relativity : the eigenvector of the detector response matrix with eigenvalue closest to zero can be used to estimate the direction of the source . observer - dependent theories require prior knowledge of the polarization states of the wave before any estimate of the direction can be made . once these are known it should be straightforward to adapt the eigenvector technique to estimate the direction . in the case of an impulsive excitation , the eigenvector corresponding to the direction has an eigenvalue that is opposite in sign and greater in magnitude than the two other eigenvalues . converting the eigenvectors to a direction again comes from eqs . ( [ eqn : gamma ] ) and  ( [ eqn : beta ] ) . the eigenvector solution is very convenient in that the inverse problem is reduced to solving a trivial eigenvalue problem . the solution is computationally simple , making this technique very efficient for use in an automated data analysis system . this feature may be important if one considers using a large number of candidate gravitational wave events in a coincidence exchange between several detectors where the source direction is used as a criterion to veto excess coincidences . the main restrictions on the eigenvector solution is that the mode channels must be independent and the noise normally distributed with equal variance . these restrictions can ideally be satisfied for a number of transducer arrangements  @xcite . we found that the eigenvector solution corresponds exactly to the maximum likelihood method under these conditions . it may be possible to apply this solution when the noise is not gaussian or is different for each mode channel , however further research is necessary to verify this extension .    through a number of numerical simulations as well as examination of the work of others @xcite we found that the errors due to the noise on a direction estimation are independent of the source location and wave amplitude for a given snr . however , the estimation of the polarization amplitudes using eqs . ( [ eqn : h_p_ls ] ) and  ( [ eqn : h_x_ls ] ) lead to direction dependent uncertainties . for example , fig . [ fig : snr_alpha ] shows the variance on the polarization angle @xmath143 for a range of snr and several values of @xmath19 found from a monte carlo type simulation . notice that the variance increases for low values of @xmath19 . this realization is disturbing given that a spherical antenna is equally sensitive to waves from all directions and polarizations . one might consider using a different coordinate system to try to avoid the directions with very poor estimates of the two polarization amplitudes . for example , use the xyz - convention of the euler angles where the first and the last rotations are not the same . this actually will not solve our problem , but instead change the directions in the sky which lead to the poor estimates . if we transform back from this coordinate system to the y - convention we just reintroduce the errors and thus have gained nothing . this dependency on the source direction is not unique to a sphere , a network of bars or interferometers will also suffer from this problem @xcite . this leads us to believe that we are excluding a piece of information from our procedures . the solution may lie in using the information from the two other eigenvectors of the detector response . in the above derivations these eigenvectors were simply discarded , but they also contain information about the gravitational wave that may eliminate these direction dependent errors . this approach will be the topic of a future paper  @xcite . while there are a few limitations to the eigenvector solution , its simplicity makes it easily extendable to other types of excitations . as discussed above , impulsive excitations can be located using this technique . as a practical example we recall that this solution was successfully tested on experiments with the lsu prototype spherical antenna @xcite . this practical confirmation of its validity gives us the confidence that it can be implemented on a real spherical antenna searching for gravitational waves . i thank m.  bassan , m.  bianchi , e.  coccia , and e.  mauceli for many useful discussions on this work . in particular , i thank j.  a.  lobo for his assistance and advice . i also thank the referee for suggesting part of the argument presented in sec . [ sec : noisy ] .
Abstract:

Answer: a spherical gravitational wave antenna is distinct from other types of gravitational wave antennas in that only a single detector is necessary to determine the direction and polarization of a gravitational wave . zhou and michelson showed that the inverse problem can be solved using the maximum likelihood method if the detector outputs are independent and have normally distributed noise with the same variance . this paper presents an analytic solution using only linear algebra that is found to produce identical results as the maximum likelihood method but with less computational burden . applications of this solution to gravitational waves in alternative symmetric metric theories of gravity and impulsive excitations also are discussed .