GenerateRing.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 Duncan Brown
00003 *
00004 *  This program is free software; you can redistribute it and/or modify
00005 *  it under the terms of the GNU General Public License as published by
00006 *  the Free Software Foundation; either version 2 of the License, or
00007 *  (at your option) any later version.
00008 *
00009 *  This program is distributed in the hope that it will be useful,
00010 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 *  GNU General Public License for more details.
00013 *
00014 *  You should have received a copy of the GNU General Public License
00015 *  along with with program; see the file COPYING. If not, write to the
00016 *  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00017 *  MA  02111-1307  USA
00018 */
00019 
00020 /************************** <lalVerbatim file="GenerateRingCV">
00021 Author: Goggin, L. M., and Brown, D. A.
00022 $Id: GenerateRing.c,v 1.3 2007/06/08 14:41:52 bema Exp $
00023 **************************************************** </lalVerbatim> */
00024 
00025 /********************************************************** <lalLaTeX>
00026 
00027 \providecommand{\lessim}{\stackrel{<}{\scriptstyle\sim}}
00028 
00029 \subsection{Module \texttt{GenerateRing.c}}
00030 \label{ss:GenerateRing.c}
00031 
00032 Computes the ringdown waveform with specified $h_{rss}$.
00033 
00034 \subsubsection*{Prototypes}
00035 \vspace{0.1in}
00036 \input{GenerateRingCP}
00037 \idx{LALGenerateRing()}
00038 
00039 \subsubsection*{Description}
00040 
00041 This function the following burst waveforms:
00042 \begin{description}
00043 \item[Sine-Gaussian]:  exponentially decaying sinusoid with specified frequency and decay constant.
00044 \end{description}
00045 
00046 \subsubsection*{Uses}
00047 \begin{verbatim}
00048 LALMalloc()                   LALFree()
00049 LALSCreateVectorSequence()    LALSDestroyVectorSequence()
00050 LALSCreateVector()            LALSDestroyVector()
00051 LALDCreateVector()            LALDDestroyVector()
00052 LALSnprintf()
00053 \end{verbatim}
00054 
00055 \subsubsection*{Notes}
00056 
00057 \vfill{\footnotesize\input{GenerateRingCV}}
00058 
00059 ******************************************************* </lalLaTeX> */
00060 
00061 #include <lal/LALStdio.h>
00062 #include <lal/LALStdlib.h>
00063 #include <lal/LALConstants.h>
00064 #include <lal/Units.h>
00065 #include <lal/Date.h>
00066 #include <lal/AVFactories.h>
00067 #include <lal/SeqFactories.h>
00068 #include <lal/VectorOps.h>
00069 #include <lal/Inject.h>
00070 #include <lal/SimulateCoherentGW.h>
00071 #include <lal/GenerateRing.h>
00072 #include <lal/LIGOMetadataTables.h>
00073 #include <lal/RealFFT.h>
00074 
00075 
00076 NRCSID( GENERATERINGC, "$Id: GenerateRing.c,v 1.3 2007/06/08 14:41:52 bema Exp $" );
00077 
00078 /* <lalVerbatim file="GenerateRingCP"> */
00079 void
00080 LALGenerateRing( 
00081     LALStatus          *stat, 
00082     CoherentGW         *output,
00083     REAL4TimeSeries    *series,
00084     SimRingdownTable   *simRingdown,
00085     RingParamStruc     *params
00086     )
00087     
00088 { /* </lalVerbatim> */
00089   UINT4 n, i;      /* number of and index over samples */
00090   REAL8 t, dt;         /* time, interval */
00091   REAL8 t0, gtime ;    /* central time, decay time */
00092   REAL8 f0, quality;   /* frequency and quality factor */
00093   REAL8 twopif0;       /* 2*pi*f0 */
00094   REAL4 h0;            /* peak strain for ringdown */
00095   REAL4 *fData;        /* pointer to frequency data */
00096   REAL8 *phiData;      /* pointer to phase data */
00097   REAL8 init_phase;    /*initial phase of injection */
00098   REAL4 *aData;        /* pointer to frequency data */
00099   LIGOTimeGPS startTime;  /* start time of injection */
00100   REAL4TimeSeries signal; /* start time of block that injection is injected into */
00101   LALTimeInterval  interval;
00102   UINT4 nPointInj; /* number of data points in a block */
00103   INT8 geoc_tns;       /* geocentric_start_time of the injection in ns */
00104   INT8 block_tns;      /* start time of block in ns */
00105   REAL8 deltaTns;
00106   INT8 inj_diff;       /* time between start of segment and injection */
00107   LALTimeInterval dummyInterval;
00108   
00109  
00110   INITSTATUS( stat, "LALGenerateRing", GENERATERINGC );
00111   ATTATCHSTATUSPTR( stat );
00112 
00113   /* Make sure parameter and output structures exist. */
00114   ASSERT( params, stat, GENERATERINGH_ENUL,
00115           GENERATERINGH_MSGENUL );
00116   ASSERT( output, stat, GENERATERINGH_ENUL,
00117           GENERATERINGH_MSGENUL );
00118 
00119   /* Make sure output fields don't exist. */
00120   ASSERT( !( output->a ), stat, GENERATERINGH_EOUT,
00121           GENERATERINGH_MSGEOUT );
00122   ASSERT( !( output->f ), stat, GENERATERINGH_EOUT,
00123           GENERATERINGH_MSGEOUT );
00124   ASSERT( !( output->phi ), stat, GENERATERINGH_EOUT,
00125           GENERATERINGH_MSGEOUT );
00126   ASSERT( !( output->shift ), stat, GENERATERINGH_EOUT,
00127           GENERATERINGH_MSGEOUT );
00128   
00129 
00130   /* Set up some other constants, to avoid repeated dereferencing. */
00131   dt = params->deltaT; 
00132   startTime = simRingdown->geocent_start_time;
00133 /* N_point = 2 * floor(0.5+ 1/ dt); */
00134  
00135   nPointInj = 163840;
00136   
00137   /* Generic ring parameters */
00138   h0 = simRingdown->amplitude;
00139   quality = (REAL8)simRingdown->quality;
00140   f0 = (REAL8)simRingdown->frequency;
00141   twopif0 = f0*LAL_TWOPI;
00142   init_phase = simRingdown->phase;
00143 
00144  
00145   if ( ( output->a = (REAL4TimeVectorSeries *)
00146          LALMalloc( sizeof(REAL4TimeVectorSeries) ) ) == NULL ) {
00147     ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM );
00148   }
00149   memset( output->a, 0, sizeof(REAL4TimeVectorSeries) );
00150   if ( ( output->f = (REAL4TimeSeries *)
00151          LALMalloc( sizeof(REAL4TimeSeries) ) ) == NULL ) {
00152     LALFree( output->a ); output->a = NULL;
00153     ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM );
00154   }
00155   memset( output->f, 0, sizeof(REAL4TimeSeries) );
00156   if ( ( output->phi = (REAL8TimeSeries *)
00157          LALMalloc( sizeof(REAL8TimeSeries) ) ) == NULL ) {
00158     LALFree( output->a ); output->a = NULL;
00159     LALFree( output->f ); output->f = NULL;
00160     ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM );
00161   }
00162   memset( output->phi, 0, sizeof(REAL8TimeSeries) );
00163 
00164   /* Set output structure metadata fields. */
00165   output->position.longitude = simRingdown->longitude; 
00166   output->position.latitude = simRingdown->latitude;
00167   output->position.system = params->system;
00168   output->psi = simRingdown->polarization;
00169    /* set epoch of output time series to that of the block */
00170   output->a->epoch = output->f->epoch = output->phi->epoch = simRingdown->geocent_start_time;
00171   output->a->deltaT = params->deltaT; 
00172   output->f->deltaT = output->phi->deltaT = params->deltaT; 
00173   output->a->sampleUnits = lalStrainUnit;
00174   output->f->sampleUnits = lalHertzUnit;
00175   output->phi->sampleUnits = lalDimensionlessUnit;
00176   LALSnprintf( output->a->name, LALNameLength, "Ring amplitudes" );
00177   LALSnprintf( output->f->name, LALNameLength, "Ring frequency" );
00178   LALSnprintf( output->phi->name, LALNameLength, "Ring phase" );
00179 
00180 
00181   /* Allocate phase and frequency arrays. */
00182   LALSCreateVector( stat->statusPtr, &( output->f->data ), nPointInj );
00183   BEGINFAIL( stat ) {
00184     LALFree( output->a );   output->a = NULL;
00185     LALFree( output->f );   output->f = NULL;
00186     LALFree( output->phi ); output->phi = NULL;
00187   } ENDFAIL( stat );
00188   
00189   LALDCreateVector( stat->statusPtr, &( output->phi->data ), nPointInj );
00190   BEGINFAIL( stat ) {
00191     TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
00192          stat );
00193     LALFree( output->a );   output->a = NULL;
00194     LALFree( output->f );   output->f = NULL;
00195     LALFree( output->phi ); output->phi = NULL;
00196   } ENDFAIL( stat );
00197 
00198 
00199   /* Allocate amplitude array. */
00200   {
00201     CreateVectorSequenceIn in; /* input to create output->a */
00202     in.length = nPointInj;
00203     in.vectorLength = 2;
00204     LALSCreateVectorSequence( stat->statusPtr, &(output->a->data), &in );
00205     BEGINFAIL( stat ) {
00206       TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
00207            stat );
00208       TRY( LALDDestroyVector( stat->statusPtr, &( output->phi->data ) ),
00209            stat );
00210       LALFree( output->a );   output->a = NULL;
00211       LALFree( output->f );   output->f = NULL;
00212       LALFree( output->phi ); output->phi = NULL;
00213     } ENDFAIL( stat );
00214   }
00215   
00216 
00217   /*  set arrays to zero */
00218   memset( output->f->data->data, 0, sizeof( REAL4 ) *  output->f->data->length );
00219   memset( output->phi->data->data, 0, sizeof( REAL8 ) * output->phi->data->length );
00220   memset( output->a->data->data, 0, sizeof( REAL4 ) * 
00221       output->a->data->length * output->a->data->vectorLength );
00222 
00223 /* Fill frequency and phase arrays starting at time of injection NOT start */
00224   fData = output->f->data->data;
00225   phiData = output->phi->data->data;
00226   aData = output->a->data->data;
00227 
00228   if ( !( strcmp( simRingdown->waveform, "Ringdown" ) ) )
00229   {
00230     for ( i = 0; i < nPointInj; i++ )
00231     {
00232       t = i * dt;
00233       gtime = twopif0 / 2 / quality * t ;
00234       *(fData++)   = f0;
00235       *(phiData++) = twopif0 * t+init_phase;
00236       *(aData++) = h0 * ( 1.0 + pow( cos( simRingdown->inclination ), 2 ) ) * 
00237         exp( - gtime );
00238       *(aData++) = h0* 2.0 * cos( simRingdown->inclination ) * exp( - gtime );
00239     }
00240   }
00241   else
00242   {
00243     ABORT( stat, GENERATERINGH_ETYP, GENERATERINGH_MSGETYP );
00244   }
00245 
00246   
00247 /* Set output field and return. */
00248   DETATCHSTATUSPTR( stat );
00249   RETURN( stat );
00250 }
00251 
00252 
00253 /* <lalVerbatim file="GenerateRingCP"> */
00254 void
00255 LALRingInjectSignals( 
00256     LALStatus               *stat, 
00257     REAL4TimeSeries         *series,
00258     SimRingdownTable        *injections,
00259     COMPLEX8FrequencySeries *resp,
00260     INT4                     calType
00261     )
00262 /* </lalVerbatim> */
00263 {
00264   UINT4              k;
00265   INT4               injStartTime;
00266   INT4               injStopTime;
00267   DetectorResponse   detector;
00268   COMPLEX8Vector    *unity = NULL;
00269   CoherentGW         waveform;
00270   RingParamStruc     ringParam;
00271   REAL4TimeSeries    signal;
00272   SimRingdownTable  *simRingdown=NULL;
00273   LALDetector       *tmpDetector=NULL /*,*nullDetector=NULL*/;
00274   COMPLEX8FrequencySeries    *transfer = NULL;
00275 
00276   INITSTATUS( stat, "LALRingInjectSignals", GENERATERINGC );
00277   ATTATCHSTATUSPTR( stat );
00278 
00279   /* set up start and end of injection zone TODO: fix this hardwired 10 */
00280   injStartTime = series->epoch.gpsSeconds - 10;
00281   injStopTime = series->epoch.gpsSeconds + 10 + (INT4)(series->data->length
00282       * series->deltaT);
00283 
00284   /* 
00285    *compute the transfer function 
00286    */
00287 
00288   /* allocate memory and copy the parameters describing the freq series */
00289   memset( &detector, 0, sizeof( DetectorResponse ) );
00290   transfer = (COMPLEX8FrequencySeries *)
00291     LALCalloc( 1, sizeof(COMPLEX8FrequencySeries) );
00292   if ( ! transfer ) 
00293   {
00294     ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM );
00295   }
00296   memcpy( &(transfer->epoch), &(resp->epoch),
00297       sizeof(LIGOTimeGPS) );
00298   transfer->f0 = resp->f0;
00299   transfer->deltaF = resp->deltaF;
00300 
00301   tmpDetector = detector.site = (LALDetector *) LALMalloc( sizeof(LALDetector) );
00302   /* set the detector site */
00303   switch ( series->name[0] )
00304   {
00305     case 'H':
00306       *(detector.site) = lalCachedDetectors[LALDetectorIndexLHODIFF];
00307       LALWarning( stat, "computing waveform for Hanford." );
00308       break;
00309     case 'L':
00310       *(detector.site) = lalCachedDetectors[LALDetectorIndexLLODIFF];
00311       LALWarning( stat, "computing waveform for Livingston." );
00312       break;
00313     default:
00314       LALFree( detector.site );
00315       detector.site = NULL;
00316       tmpDetector = NULL;
00317       LALWarning( stat, "Unknown detector site, computing plus mode "
00318           "waveform with no time delay" );
00319       break;
00320   }
00321 
00322   /* set up units for the transfer function */
00323   {
00324     RAT4 negOne = { -1, 0 };
00325     LALUnit unit;
00326     LALUnitPair pair;
00327     pair.unitOne = &lalADCCountUnit;
00328     pair.unitTwo = &lalStrainUnit;
00329     LALUnitRaise( stat->statusPtr, &unit, pair.unitTwo, &negOne );
00330     CHECKSTATUSPTR( stat );
00331     pair.unitTwo = &unit;
00332     LALUnitMultiply( stat->statusPtr, &(transfer->sampleUnits),
00333         &pair );
00334     CHECKSTATUSPTR( stat );
00335   }
00336 
00337   /* invert the response function to get the transfer function */
00338   LALCCreateVector( stat->statusPtr, &( transfer->data ),
00339       resp->data->length );
00340   CHECKSTATUSPTR( stat );
00341 
00342   LALCCreateVector( stat->statusPtr, &unity, resp->data->length );
00343   CHECKSTATUSPTR( stat );
00344   for ( k = 0; k < resp->data->length; ++k ) 
00345   {
00346     unity->data[k].re = 1.0;
00347     unity->data[k].im = 0.0;
00348   }
00349 
00350   LALCCVectorDivide( stat->statusPtr, transfer->data, unity,
00351       resp->data );
00352   CHECKSTATUSPTR( stat );
00353 
00354   LALCDestroyVector( stat->statusPtr, &unity );
00355   CHECKSTATUSPTR( stat );
00356 
00357   /* Set up a time series to hold signal in ADC counts */
00358   signal.deltaT = series->deltaT;
00359   if ( ( signal.f0 = series->f0 ) != 0 )
00360   {
00361     ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM );
00362   }
00363   signal.sampleUnits = lalADCCountUnit;
00364 
00365   signal.data=NULL;
00366   LALSCreateVector( stat->statusPtr, &(signal.data), 
00367       series->data->length );
00368   CHECKSTATUSPTR( stat );
00369 
00370   /* loop over list of waveforms and inject into data stream */
00371   simRingdown = injections;
00372   while ( simRingdown )
00373   {
00374     /* only do the work if the ring is in injection zone */
00375     if( (injStartTime - simRingdown->geocent_start_time.gpsSeconds) *
00376         (injStopTime - simRingdown->geocent_start_time.gpsSeconds) > 0 )
00377     {
00378       simRingdown = simRingdown->next;
00379       continue;
00380     }
00381 
00382     /* set the ring params */
00383     ringParam.deltaT = series->deltaT;
00384     if( !( strcmp( simRingdown->coordinates, "HORIZON" ) ) )
00385     {
00386       ringParam.system = COORDINATESYSTEM_HORIZON;
00387     }
00388     else if ( !( strcmp( simRingdown->coordinates, "ZENITH" ) ) )
00389     {
00390       /* set coordinate system for completeness */
00391       ringParam.system = COORDINATESYSTEM_EQUATORIAL;
00392       detector.site = NULL;
00393     }
00394     else if ( !( strcmp( simRingdown->coordinates, "GEOGRAPHIC" ) ) )
00395     {
00396      ringParam.system = COORDINATESYSTEM_GEOGRAPHIC;
00397     }
00398     else if ( !( strcmp( simRingdown->coordinates, "EQUATORIAL" ) ) )
00399     {
00400       ringParam.system = COORDINATESYSTEM_EQUATORIAL;
00401     }
00402     else if ( !( strcmp( simRingdown->coordinates, "ECLIPTIC" ) ) )
00403     {
00404       ringParam.system = COORDINATESYSTEM_ECLIPTIC;
00405     }
00406     else if ( !( strcmp( simRingdown->coordinates, "GALACTIC" ) ) )
00407     {
00408       ringParam.system = COORDINATESYSTEM_GALACTIC;
00409     }
00410     else
00411       ringParam.system = COORDINATESYSTEM_EQUATORIAL;
00412 
00413     /* generate the ring */
00414     memset( &waveform, 0, sizeof(CoherentGW) );
00415     LALGenerateRing( stat->statusPtr, &waveform, series, simRingdown, &ringParam );
00416     CHECKSTATUSPTR( stat );
00417 
00418     /* print the waveform to a file */
00419     if ( 0 )
00420       {
00421         FILE *fp;
00422         char fname[512];
00423         UINT4 jj, kplus, kcross;
00424         LALSnprintf( fname, sizeof(fname) / sizeof(*fname), 
00425             "waveform-%d-%d-%s.txt", 
00426             simRingdown->geocent_start_time.gpsSeconds,
00427             simRingdown->geocent_start_time.gpsNanoSeconds,
00428             simRingdown->waveform );
00429         fp = fopen( fname, "w" );
00430          
00431         for( jj = 0, kplus = 0, kcross = 1; jj < waveform.phi->data->length; 
00432             ++jj, kplus += 2, kcross +=2 )
00433           {
00434             fprintf(fp, "%d %e %e %le %e\n", jj,
00435                 waveform.a->data->data[kplus], 
00436                 waveform.a->data->data[kcross], 
00437                 waveform.phi->data->data[jj], 
00438                 waveform.f->data->data[jj]);
00439             }
00440         fclose( fp );     
00441         }
00442     /* end */
00443 #if 0
00444     fprintf( stderr, "a->epoch->gpsSeconds = %d\na->epoch->gpsNanoSeconds = %d\n",
00445         waveform.a->epoch.gpsSeconds, waveform.a->epoch.gpsNanoSeconds );
00446     fprintf( stderr, "phi->epoch->gpsSeconds = %d\nphi->epoch->gpsNanoSeconds = %d\n",
00447         waveform.phi->epoch.gpsSeconds, waveform.phi->epoch.gpsNanoSeconds );
00448     fprintf( stderr, "f->epoch->gpsSeconds = %d\nf->epoch->gpsNanoSeconds = %d\n",
00449         waveform.f->epoch.gpsSeconds, waveform.f->epoch.gpsNanoSeconds );
00450 #endif
00451     /* must set the epoch of signal since it's used by coherent GW */
00452     signal.epoch = series->epoch;
00453     memset( signal.data->data, 0, signal.data->length * sizeof(REAL4) );
00454 
00455     /* decide which way to calibrate the data; defaul to old way */
00456     if( calType )
00457       detector.transfer=NULL;
00458     else
00459       detector.transfer=transfer;
00460     
00461     /* convert this into an ADC signal */
00462     LALSimulateCoherentGW( stat->statusPtr, 
00463         &signal, &waveform, &detector );
00464     CHECKSTATUSPTR( stat );
00465 
00466 
00467 /* print the waveform to a file */
00468     if ( 0 )
00469       {
00470         FILE *fp;
00471         char fname[512];
00472         UINT4 jj;
00473         LALSnprintf( fname, sizeof(fname) / sizeof(*fname),
00474             "signal-%d-%d-%s.txt",
00475             simRingdown->geocent_start_time.gpsSeconds,
00476             simRingdown->geocent_start_time.gpsNanoSeconds,
00477             simRingdown->waveform );
00478         fp = fopen( fname, "w" );
00479 
00480         for( jj = 0; jj < signal.data->length; ++jj )
00481           {
00482             fprintf( fp, "%d %le\n", jj, signal.data->data[jj] );
00483           }
00484         fclose( fp );
00485         }
00486     /* end */
00487 #if 0
00488     fprintf( stderr, "series.epoch->gpsSeconds = %d\nseries.epoch->gpsNanoSeconds = %d\n",
00489         series->epoch.gpsSeconds, series->epoch.gpsNanoSeconds );
00490     fprintf( stderr, "signal->epoch->gpsSeconds = %d\nsignal->epoch->gpsNanoSeconds = %d\n",
00491         signal.epoch.gpsSeconds, signal.epoch.gpsNanoSeconds );
00492 #endif
00493     /* if calibration using RespFilt */
00494     if( calType == 1 )
00495       XLALRespFilt(&signal, transfer);
00496 
00497     /* inject the signal into the data channel */
00498     LALSSInjectTimeSeries( stat->statusPtr, series, &signal );
00499     CHECKSTATUSPTR( stat );
00500     
00501 /* free memory in coherent GW structure.  TODO:  fix this */
00502     LALSDestroyVectorSequence( stat->statusPtr, &( waveform.a->data ) );
00503     CHECKSTATUSPTR( stat );
00504     LALSDestroyVector( stat->statusPtr, &( waveform.f->data ) );
00505     CHECKSTATUSPTR( stat );
00506     LALDDestroyVector( stat->statusPtr, &( waveform.phi->data ) );
00507     CHECKSTATUSPTR( stat );
00508     LALFree( waveform.a );   waveform.a = NULL;
00509     LALFree( waveform.f );   waveform.f = NULL;
00510     LALFree( waveform.phi );  waveform.phi = NULL;
00511 
00512     /* reset the detector site information in case it changed */
00513     detector.site = tmpDetector;
00514 
00515     /* move on to next one */
00516     simRingdown = simRingdown->next;
00517   }
00518 
00519   /* destroy the signal */
00520   LALSDestroyVector( stat->statusPtr, &(signal.data) );
00521   CHECKSTATUSPTR( stat );
00522 
00523   LALCDestroyVector( stat->statusPtr, &( transfer->data ) );
00524   CHECKSTATUSPTR( stat );
00525 
00526   if ( detector.site ) LALFree( detector.site );
00527   LALFree( transfer );
00528 
00529   DETATCHSTATUSPTR( stat );
00530   RETURN( stat );
00531 }

Generated on Thu Aug 28 03:12:19 2008 for LAL by  doxygen 1.5.2