source: BAORadio/AmasNancay/trunk/mergeRawOnOff.cc @ 552

Last change on this file since 552 was 552, checked in by campagne, 13 years ago

improvment (jec)

File size: 14.5 KB
Line 
1// Utilisation de SOPHYA pour faciliter les tests ...
2#include <regex.h>
3//#include <regexp.h>
4#include <stdio.h>
5
6#include "sopnamsp.h"
7#include "machdefs.h"
8
9#include <stdlib.h>
10#include <dirent.h>
11#include <matharr.h>
12
13// include standard c/c++
14#include <iostream>
15#include <fstream>
16#include <string>
17#include <vector>
18#include <map>
19#include <functional>
20#include <algorithm>
21#include <numeric>
22#include <list>
23#include <exception>
24
25// include sophya mesure ressource CPU/memoire ...
26#include "resusage.h"
27#include "ctimer.h"
28#include "timing.h"
29#include "timestamp.h"
30#include "strutilxx.h"
31#include "ntuple.h"
32#include "fioarr.h"
33#include "tarrinit.h"
34#include "histinit.h"
35#include "fitsioserver.h"
36#include "fiosinit.h"
37#include "ppersist.h"
38
39//-----------------------------------------------
40const sa_size_t NUMBER_OF_CHANNELS = 2;
41const sa_size_t NUMBER_OF_FREQ     = 8192;
42const sa_size_t TOTAL_NUM_CYCLES   = 10000;
43const r_4    LOWER_FREQUENCY = 1250.0; //MHz
44const r_4    TOTAL_BANDWIDTH = 250.0; //MHz
45//-----------------------------------------------
46//Input parameters
47struct Param {
48  int debuglev_;      //debug
49  string inPath_;     //root directory of the input files
50  string outPath_;    //output files are located here
51  string sourceName_; //source name & subdirectory of the input files
52  string ppfFile_;    //generic name of the input files
53  int nSliceInFreq_;  //used by reduceSpectra() fnc
54} para;
55//--------------------------------------------------------------
56//Utility functions
57
58  class median_of_empty_list_exception:public std::exception{
59    virtual const char* what() const throw() {
60    return "Attempt to take the median of an empty list of numbers.  "
61      "The median of an empty list is undefined.";
62  }
63  };
64  template<class RandAccessIter>
65    double median(RandAccessIter begin, RandAccessIter end) 
66    throw(median_of_empty_list_exception){
67    if(begin == end){ throw median_of_empty_list_exception(); }
68    std::size_t size = end - begin;
69    std::size_t middleIdx = size/2;
70    RandAccessIter target = begin + middleIdx;
71    std::nth_element(begin, target, end);
72   
73    if(size % 2 != 0){ //Odd number of elements
74      return *target;
75    }else{            //Even number of elements
76      double a = *target;
77      RandAccessIter targetNeighbor= target-1;
78      std::nth_element(begin, targetNeighbor, end);
79      return (a+*targetNeighbor)/2.0;
80    }
81  }
82
83//--------------------------------------------------------------
84char *regexp (const char *string, const char *patrn, int *begin, int *end) {   
85        int i, w=0, len;                 
86        char *word = NULL;
87        regex_t rgT;
88        regmatch_t match;
89        regcomp(&rgT,patrn,REG_EXTENDED);
90        if ((regexec(&rgT,string,1,&match,0)) == 0) {
91                *begin = (int)match.rm_so;
92                *end = (int)match.rm_eo;
93                len = *end-*begin;
94                word=(char*)malloc(len+1);
95                for (i=*begin; i<*end; i++) {
96                        word[w] = string[i];
97                        w++; }
98                word[w]=0;
99        }
100        regfree(&rgT);
101        return word;
102}
103//-------
104sa_size_t round_sa(r_4 r) {
105  return static_cast<sa_size_t>((r > 0.0) ? (r + 0.5) : (r - 0.5));
106}
107//-----
108string StringToLower(string strToConvert){
109  //change each element of the string to lower case
110  for(unsigned int i=0;i<strToConvert.length();i++) {
111    strToConvert[i] = tolower(strToConvert[i]);
112  }
113  return strToConvert;//return the converted string
114}
115//-----
116bool stringCompare( const string &left, const string &right ){
117   if( left.size() < right.size() )
118      return true;
119   for( string::const_iterator lit = left.begin(), rit = right.begin(); lit != left.end() && rit != right.end(); ++lit, ++rit )
120      if( tolower( *lit ) < tolower( *rit ) )
121         return true;
122      else if( tolower( *lit ) > tolower( *rit ) )
123         return false;
124   return false;
125}
126//-----
127list<string> ListOfFileInDir(string dir, string filePettern) throw(string) {
128  list<string> theList;
129
130
131  DIR *dip;
132  struct dirent *dit;
133  string msg;  string fileName;
134  string fullFileName;
135  size_t found;
136
137  if ((dip=opendir(dir.c_str())) == NULL ) {
138    msg = "opendir failed on directory "+dir;
139    throw msg;
140  }
141  while ( (dit = readdir(dip)) != NULL ) {
142    fileName = dit->d_name;
143    found=fileName.find(filePettern);
144    if (found != string::npos) {
145      fullFileName = dir + "/";
146      fullFileName += fileName;
147      theList.push_back(fullFileName);
148    }
149  }//eo while
150  if (closedir(dip) == -1) {
151    msg = "closedir failed on directory "+dir;
152    throw msg;
153  }
154 
155  theList.sort(stringCompare);
156
157  return theList;
158
159}
160//
161class  StringMatch : public unary_function<string,bool> {
162public:
163  StringMatch(const string& pattern): pattern_(pattern){}
164  bool operator()(const string& aStr) const {
165
166
167    int b,e;
168    regexp(aStr.c_str(),pattern_.c_str(),&b,&e);
169
170//     cout << "investigate " << aStr << " to find " << pattern_
171//       << "[" <<b<<","<<e<<"]"
172//       << endl;
173
174   
175    if (b != 0) return false;
176    if (e != (int)aStr.size()) return false;
177    return true;
178
179  }
180private:
181  string pattern_;
182};
183//-------------------------------------------------------
184//Rebin in frequence + compute mean and sigma
185void reduceSpectra(const TMatrix<r_4>& specMtxInPut, 
186                    TMatrix<r_4>& meanMtx, 
187                    TMatrix<r_4>& sigmaMtx) {
188  sa_size_t nSliceFreq = para.nSliceInFreq_;
189  sa_size_t deltaFreq =  NUMBER_OF_FREQ/nSliceFreq;
190  for (sa_size_t iSlice=0; iSlice<nSliceFreq; iSlice++){
191    sa_size_t freqLow= iSlice*deltaFreq;
192    sa_size_t freqHigh= freqLow + deltaFreq -1;
193    for (sa_size_t iCh=0; iCh<NUMBER_OF_CHANNELS; ++iCh){
194      TVector<r_4> reducedRow;
195      reducedRow = specMtxInPut.SubMatrix(Range(iCh),Range(freqLow,freqHigh)).CompactAllDimensions();
196      double mean; 
197      double sigma;
198      MeanSigma(reducedRow,mean,sigma);
199      meanMtx(iCh,iSlice) = mean;
200      sigmaMtx(iCh,iSlice) = sigma;
201    }//eo loop on channels
202  }//eo loop on slices
203}
204//-------------------------------------------------------
205//Compute the mean of Raw spectra and also the mean/sigma of rebinned spectra
206//Used like:
207//
208void meanOnCycles() throw(string) {
209  list<string> listOfFiles;
210  string directoryName;
211  directoryName = para.inPath_ + "/" + para.sourceName_;
212
213  //Make the listing of the directory
214  listOfFiles = ListOfFileInDir(directoryName,para.ppfFile_);
215 
216  list<string>::const_iterator iFile, iFileEnd, iSpec, iSpecEnd;
217  iFileEnd = listOfFiles.end();
218 
219  StringMatch match("specONOFFRaw[0-9]+"); //Tag of the PPF objects
220  TMatrix<r_4> meanOfSpectra(NUMBER_OF_CHANNELS,NUMBER_OF_FREQ);
221  uint_4 nSpectra=0;
222  //Loop on files
223  for (iFile = listOfFiles.begin(); iFile != iFileEnd; ++iFile) {
224    if (para.debuglev_>90){
225      cout << "load file <" << *iFile << ">" << endl;
226    }
227    PInPersist fin(*iFile);
228    vector<string> vec = fin.GetNameTags();
229    list<string> listOfSpectra;
230    //Keep only required PPF objects
231    std::remove_copy_if(
232                        vec.begin(), vec.end(), back_inserter(listOfSpectra),
233                        not1(match)
234                        );
235   
236    iSpecEnd = listOfSpectra.end();
237    listOfSpectra.sort(stringCompare);
238    //Loop of spectra matrix
239    for (iSpec = listOfSpectra.begin(); iSpec !=iSpecEnd;  ++iSpec){
240      if (para.debuglev_>90){
241        cout << " spactra <" << *iSpec << ">" << endl;
242      }
243      TMatrix<r_4> aSpec(NUMBER_OF_CHANNELS,NUMBER_OF_FREQ);
244      fin.GetObject(aSpec,*iSpec);
245      //How to see if the GetObject is ok?? Ask Reza
246      nSpectra++;
247      meanOfSpectra+=aSpec;
248    }//eo loop on spectra in a file
249  }//eo loop on files
250 
251  //Normalisation
252  if(nSpectra>0)meanOfSpectra/=(r_4)(nSpectra);
253
254  //Compute the reduced version of the mean and sigma
255  TMatrix<r_4> meanRedMtx(NUMBER_OF_CHANNELS,para.nSliceInFreq_);
256  TMatrix<r_4> sigmaRedMtx(NUMBER_OF_CHANNELS,para.nSliceInFreq_);
257  reduceSpectra(meanOfSpectra,meanRedMtx,sigmaRedMtx);
258
259  {//Save the result
260    stringstream tmp;
261    tmp << nSpectra;
262    string fileName = para.outPath_+"/meanDiffOnOffRaw_"+StringToLower(para.sourceName_)+"-"+tmp.str()+"Cycles.ppf";
263    cout << "Save mean based on " <<  nSpectra << " cycles " << endl;
264    POutPersist fos(fileName);
265
266    string tag = "mean";
267    fos << PPFNameTag(tag) << meanOfSpectra;
268    tag = "meanred";
269    fos << PPFNameTag(tag) << meanRedMtx;
270    tag = "sigmared";
271    fos << PPFNameTag(tag) << sigmaRedMtx;
272  }
273}
274//-------------------------------------------------------
275//Compute the median of Raw spectra and also the mean/sigma of rebinned spectra
276//Used like:
277//
278void medianOnCycles() throw(string) {
279  list<string> listOfFiles;
280  string directoryName;
281  directoryName = para.inPath_ + "/" + para.sourceName_;
282
283  //Make the listing of the directory
284  listOfFiles = ListOfFileInDir(directoryName,para.ppfFile_);
285 
286  list<string>::const_iterator iFile, iFileEnd, iSpec, iSpecEnd;
287  iFileEnd = listOfFiles.end();
288 
289
290  TArray<r_4> tableOfSpectra(NUMBER_OF_FREQ,NUMBER_OF_CHANNELS,TOTAL_NUM_CYCLES); //TOTAL_NUM_CYCLES should be large enough...
291
292  StringMatch match("specONOFFRaw[0-9]+"); //Tag of the PPF objects
293  uint_4 nSpectra=0;
294  //Loop on files
295  for (iFile = listOfFiles.begin(); iFile != iFileEnd; ++iFile) {
296    if (para.debuglev_>90){
297      cout << "load file <" << *iFile << ">" << endl;
298    }
299    PInPersist fin(*iFile);
300    vector<string> vec = fin.GetNameTags();
301    list<string> listOfSpectra;
302    //Keep only required PPF objects
303    std::remove_copy_if(
304                        vec.begin(), vec.end(), back_inserter(listOfSpectra),
305                        not1(match)
306                        );
307   
308    iSpecEnd = listOfSpectra.end();
309    listOfSpectra.sort(stringCompare);
310    //Loop of spectra matrix
311    for (iSpec = listOfSpectra.begin(); iSpec !=iSpecEnd;  ++iSpec){
312      if (para.debuglev_>90){
313        cout << " spactra <" << *iSpec << ">" << endl;
314      }
315      TMatrix<r_4> aSpec(NUMBER_OF_CHANNELS,NUMBER_OF_FREQ);
316      fin.GetObject(aSpec,*iSpec);
317
318      if ((sa_size_t)nSpectra < TOTAL_NUM_CYCLES ) {
319        tableOfSpectra(Range::all(),Range::all(),Range(nSpectra)) = aSpec;
320      } else {
321        stringstream tmp;
322        tmp<<nSpectra;
323        throw "FATAL: SIZE ERROR: too many cycles:"+tmp.str();
324      }
325      nSpectra++;
326    }//eo loop on spectra in a file
327  }//eo loop on files
328 
329  //Resize
330
331 
332  TMatrix<r_4> medianOfSpectra(NUMBER_OF_CHANNELS,NUMBER_OF_FREQ);
333  //Compute the median for each freq. and Channel
334  for (sa_size_t iCh=0; iCh<NUMBER_OF_CHANNELS; iCh++){
335    for (sa_size_t freq =0; freq<NUMBER_OF_FREQ; freq++){
336      TVector<r_4> tmp0(tableOfSpectra(Range(freq),Range(iCh),Range(0,nSpectra-1)).CompactAllDimensions());
337      vector<r_4> tmp;
338      tmp0.FillTo(tmp);
339      medianOfSpectra(iCh,freq) = median(tmp.begin(),tmp.end());
340    }
341  }
342
343
344  //Compute the reduced version of the mean and sigma
345  TMatrix<r_4> meanRedMtx(NUMBER_OF_CHANNELS,para.nSliceInFreq_);
346  TMatrix<r_4> sigmaRedMtx(NUMBER_OF_CHANNELS,para.nSliceInFreq_);
347  reduceSpectra(medianOfSpectra,meanRedMtx,sigmaRedMtx);
348
349  {//Save the result
350    stringstream tmp;
351    tmp << nSpectra;
352    string fileName = para.outPath_+"/medianDiffOnOffRaw_"+StringToLower(para.sourceName_)+"-"+tmp.str()+"Cycles.ppf";
353    cout << "Save median based on " <<  nSpectra << " cycles " << endl;
354    POutPersist fos(fileName);
355
356    string tag = "median";
357    fos << PPFNameTag(tag) << medianOfSpectra;
358    tag = "meanmedred";
359    fos << PPFNameTag(tag) << meanRedMtx;
360    tag = "sigmamedred";
361    fos << PPFNameTag(tag) << sigmaRedMtx;
362    tag = "cycleVsfreq";
363   
364    TArray<r_4> tarr(tableOfSpectra(Range::all(),Range::all(),Range(0,nSpectra-1)));
365    fos << PPFNameTag(tag) << tarr;
366  }
367}
368
369//-------------------------------------------------------
370int main(int narg, char* arg[]) {
371 
372  int rc = 0; //return code
373  string msg; //message used in Exceptions
374
375
376
377  //default value for initial parameters (see Para structure on top of the file)
378  string debuglev = "0";
379  string action = "meanDiffOnOff";
380  string inputPath = "."; 
381  string outputPath = "."; 
382  string sourceName = "Abell85";
383  string ppfFile;
384  string nSliceInFreq = "32";
385 
386 
387  //  bool okarg=false;
388  int ka=1;
389  while (ka<(narg-1)) {
390    if (strcmp(arg[ka],"-h")==0) {
391      cout << "Usage:  -act [meanDiffOnOff]|medianDiffOnOff\n"
392           << " -src [Abell85]\n -inPath [.]|<top_root_dir of the ppf file>\n" 
393           << " (ex. /sps/baoradio/AmasNancay/JEC/\n " 
394           << " -outPath [.]|<dir of the output> \n"
395           << " -nSliceInFreq [32]|<number of bin in freq. to cumulate>\n"
396           << " -ppfFile <generic name of the input ppf files> (ex. diffOnOffRaw)"
397           << " -debug <level> "
398           << endl;
399      return 0;
400    }
401    else if (strcmp(arg[ka],"-debug")==0) {
402      debuglev=arg[ka+1];
403      ka+=2;
404    }
405    else if (strcmp(arg[ka],"-act")==0) {
406      action=arg[ka+1];
407      ka+=2;
408    }
409    else if (strcmp(arg[ka],"-inPath")==0) {
410      inputPath=arg[ka+1];
411      ka+=2;
412    }
413    else if (strcmp(arg[ka],"-outPath")==0) {
414      outputPath=arg[ka+1];
415      ka+=2;
416    }
417    else if (strcmp(arg[ka],"-src")==0) {
418      sourceName=arg[ka+1];
419      ka+=2;
420    }
421    else if (strcmp(arg[ka],"-ppfFile")==0) {
422      ppfFile=arg[ka+1];
423      ka+=2;
424    }
425    else if (strcmp(arg[ka],"-nSliceInFreq")==0) {
426      nSliceInFreq=arg[ka+1];
427      ka+=2;
428    }
429    else ka++;
430  }//eo while
431
432  para.debuglev_   = atoi(debuglev.c_str());
433  para.inPath_     = inputPath;
434  para.outPath_    = outputPath;
435  para.sourceName_ = sourceName;
436  para.ppfFile_    = ppfFile;
437  para.nSliceInFreq_ = atoi(nSliceInFreq.c_str());
438
439  cout << "Dump Initial parameters ............" << endl;
440  cout << " action = " << action << "\n"
441       << " inputPath = " << para.inPath_  << "\n" 
442       << " outputPath = " <<  para.outPath_ << "\n"
443       << " sourceName = " << para.sourceName_ << "\n"
444       << " ppfFile = " <<  para.ppfFile_ << "\n"
445       << " nSliceInFreq = " << para.nSliceInFreq_  << "\n"
446       << " debuglev = "  << para.debuglev_   << "\n";
447  cout << "...................................." << endl;
448
449  if ( "" == ppfFile ) {
450    cerr << "mergeRawOnOff.cc: you have forgotten ppfFile option"
451         << endl;
452    return 999;
453  }
454
455
456  try {
457
458//     int b,e;
459//     char *match=regexp("truc0machin","[a-z]+[0-9]*",&b,&e);
460//     printf("->%s<-\n(b=%d e=%d)\n",match,b,e);
461
462    if ( action == "meanDiffOnOff" ) {
463      meanOnCycles();
464    } else if (action == "medianDiffOnOff") {
465      medianOnCycles();
466    } else {
467      msg = "Unknown action " + action;
468      throw msg;
469    }
470
471
472  }  catch (std::exception& sex) {
473    cerr << "mergeRawOnOff.cc std::exception :"  << (string)typeid(sex).name() 
474         << "\n msg= " << sex.what() << endl;
475    rc = 78;
476  }
477  catch ( string str ) {
478    cerr << "mergeRawOnOff.cc Exception raised: " << str << endl;
479  }
480  catch (...) {
481    cerr << "mergeRawOnOff.cc catched unknown (...) exception  " << endl; 
482    rc = 79; 
483  } 
484
485  return 0;
486
487}
Note: See TracBrowser for help on using the repository browser.