]> Creatis software - creaBruker.git/blob - lib/src1/brukerdataset.cpp
Added CMake configuration to enable CDash tests.
[creaBruker.git] / lib / src1 / brukerdataset.cpp
1 /*
2         # ---------------------------------------------------------------------
3         #
4         # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image 
5         #                        pour la Santé)
6         # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7         # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8         # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9         #
10         #  This software is governed by the CeCILL-B license under French law and 
11         #  abiding by the rules of distribution of free software. You can  use, 
12         #  modify and/ or redistribute the software under the terms of the CeCILL-B 
13         #  license as circulated by CEA, CNRS and INRIA at the following URL 
14         #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
15         #  or in the file LICENSE.txt.
16         #
17         #  As a counterpart to the access to the source code and  rights to copy,
18         #  modify and redistribute granted by the license, users are provided only
19         #  with a limited warranty  and the software's author,  the holder of the
20         #  economic rights,  and the successive licensors  have only  limited
21         #  liability. 
22         #
23         #  The fact that you are presently reading this means that you have had
24         #  knowledge of the CeCILL-B license and that you accept its terms.
25         # ------------------------------------------------------------------------
26 */
27         
28 //
29 // C++ Implementation: brukerdataset
30 //
31 // Description: 
32 //
33 //
34 // Author:  <Denis Grenier>, (C) 2008
35 //
36 // Copyright: See COPYING file that comes with this distribution
37 //
38 //
39
40
41 #define DEBUG 0
42
43 #include "brukerdataset.h"
44
45 BrukerDataSet::BrukerDataSet(){}
46
47
48 BrukerDataSet::~BrukerDataSet(){}
49
50
51 bool BrukerDataSet::LoadFile(std::string fileToRead)
52 {
53
54 //std::cout <<
55 //"------------- BrukerDataSet::LoadFile() Open : [" << fileToRead << "]" << std::endl;
56   std::ifstream FID;
57   char * buffer;
58   FID.open(fileToRead.c_str(), std::ios::binary);
59   if (FID.rdstate()==std::ios::failbit) {
60     //std::cout << "BrukerDataSet::LoadFile() Cannot open : [" << fileToRead << "]" << std::endl;
61     return false;
62   }
63   
64   FID.seekg (0, std::ios::end);
65   int length = FID.tellg();
66   FID.seekg (0, std::ios::beg);
67
68   buffer = new char [length];
69   FID.read (buffer,length);
70   FID.close();
71   BrukerDataSet::WholeHeader=buffer;
72   delete [] buffer;
73   return true;
74 }
75
76
77
78 std::string BrukerDataSet::SearchBufferForText(std::string& file, const boost::regex& RegExp)
79 {
80   boost::cmatch what;
81   if (regex_search(file.c_str(), what, RegExp)) 
82     return what[1];
83   return "";
84 }
85
86
87 /**
88  * 
89  * @param file 
90  * @param RegExp 
91  * @return bool
92  */
93 bool BrukerDataSet::BoolMatchBufferForText(std::string& file, const boost::regex& RegExp)
94 {
95   boost::cmatch what;
96   if (regex_match(file.c_str(), what, RegExp)) 
97   return true;
98   return false;
99 }
100
101 std::string BrukerDataSet::RemoveNewlines(std::string file)
102 {
103     boost::regex regexNewline;
104   const char* pre_expression = "[[:cntrl:]]";
105    regexNewline.assign(pre_expression);
106
107   const char* pre_format = "";
108   std::ostringstream t(std::ios::out | std::ios::binary);
109       std::ostream_iterator<char, char> oi(t);
110   boost::regex_replace(oi, file.begin(), file.end(),
111       regexNewline, pre_format, boost::match_default | boost::format_all);
112       std::string s(t.str());
113       return s;
114  }
115  
116 std::string BrukerDataSet::RemoveSpaces(std::string file)
117 {
118     boost::regex regexSpace;
119   const char* pre_expression = "[[:space:]]";
120    regexSpace.assign(pre_expression);
121
122   const char* pre_format = "";
123   std::ostringstream t(std::ios::out | std::ios::binary);
124       std::ostream_iterator<char, char> oi(t);
125   boost::regex_replace(oi, file.begin(), file.end(),
126       regexSpace, pre_format, boost::match_default | boost::format_all);
127       std::string s(t.str());
128       return s;
129  }
130
131  
132  
133
134 std::string BrukerDataSet::MatchBufferForText(std::string& file,const boost::regex& RegExp)
135 {
136   boost::cmatch what;
137   if (regex_match(file.c_str(), what, RegExp)) 
138     return what[1];
139   return "";
140 }
141
142
143
144 std::string BrukerDataSet::GetKeyword(std::string& file)
145 {
146   return MatchBufferForText( file,KeyWord);
147 }
148
149
150
151 int BrukerDataSet::GetDimensionnality(std::string& file)
152 {
153   int iterator=0;
154   std::string DimensionnalityBuffer=SearchBufferForText(file,Dimensionnality);
155   if (DimensionnalityBuffer=="") 
156     return iterator;
157   boost::match_results<std::string::const_iterator> what;
158   boost::match_flag_type flags= boost::match_default;
159   std::string::const_iterator start,end;
160   start=DimensionnalityBuffer.begin();
161   end=DimensionnalityBuffer.end();
162
163   while (regex_search(start, end, what, UnsignedInteger))
164   {
165     iterator++;
166     start=what[0].second;
167     flags |= boost::match_prev_avail;
168     flags |= boost::match_not_bob;
169   }
170   return iterator;
171 }
172
173
174
175 int BrukerDataSet::GetIntValueOfDimN(std::string& file, int N)
176 {
177   int iterator=0;
178   std::string DimensionnalityBuffer=SearchBufferForText(file,Dimensionnality);
179   if (N < 1 || DimensionnalityBuffer=="") 
180     return 0;
181   //std::cout << DimensionnalityBuffer << std::endl;
182   boost::match_results<std::string::const_iterator> what;
183   boost::match_flag_type flags= boost::match_default;
184   std::string::const_iterator start,end;
185   start=DimensionnalityBuffer.begin();
186   end=DimensionnalityBuffer.end();
187
188   for (int i=1;i<=N;i++)
189   {
190     regex_search(start,end, what, UnsignedInteger);
191     iterator++;
192     start=what[0].second;
193     flags |= boost::match_prev_avail;
194     flags |= boost::match_not_bob;
195   }
196   return atoi(std::string(what[1].first,what[1].second).c_str());
197 }
198
199
200
201 std::string BrukerDataSet::GetValuesPart(std::string& file)
202 {
203   std::string Result;
204   Result=MatchBufferForText(file,BufferNValues);
205   if (Result !="")   
206   return RemoveNewlines(Result);
207   return MatchBufferForText(file,Buffer1Value);
208 }
209
210
211 std::string BrukerDataSet::GetContentType(std::string& file)
212 {
213   std::string ValuesPart;
214    boost::match_flag_type flags = boost::match_default; 
215    std::string::const_iterator start, end;
216   ValuesPart=GetValuesPart(file);
217   start=ValuesPart.begin();
218   end=ValuesPart.end();
219   // boost regexp_match can not handle well what we want
220   // so instead of looking for a match we will seek proof of a non int serie
221   // i.e. check if we can find something else than than -0-9
222    boost::regex isNotIntSerie("[^ \\-0-9]");
223    boost::match_results<std::string::const_iterator> whatInt;
224    if (!regex_search(start,end, whatInt, isNotIntSerie,flags)) 
225      return "int";
226    
227    // if not int serie check if it's not a floats serie !!!
228    
229    boost::regex isNotFloatSerie("[^ \\-\\+\\.eE0-9]");
230    boost::match_results<std::string::const_iterator> whatFloat;
231    if (!regex_search(start,end, whatFloat, isNotFloatSerie,flags))
232      return "float";
233    
234      // if not a float serie neither, it's a string !!!
235   return "string"; 
236 }
237
238
239
240 int BrukerDataSet::GetIntValueN(std::string& file,int N)
241 {
242   std::string ValuesPart=GetValuesPart(file);
243   int iterator=0;
244   if (N < 1 || ValuesPart=="") 
245     return -32767;
246     
247   boost::match_results<std::string::const_iterator> what;
248   boost::match_flag_type flags= boost::match_default;
249   std::string::const_iterator start,end;
250   start=ValuesPart.begin();
251   end=ValuesPart.end();
252
253   while (iterator != N)
254   {
255     regex_search(start,end, what, SignedInteger);
256     iterator++;
257     start=what[0].second;
258     flags |= boost::match_prev_avail;
259     flags |= boost::match_not_bob;
260   }
261   return (atoi((std::string(what[1].first,what[1].second)).c_str()));
262 }
263
264
265
266 double BrukerDataSet::GetDoubleValueN(std::string& file, int N)
267 {
268   std::string ValuesPart=GetValuesPart(file);
269   int iterator=0;
270   if (N < 1 || ValuesPart=="") 
271     return 0;
272   boost::match_results<std::string::const_iterator> what;
273   boost::match_flag_type flags= boost::match_default;
274   std::string::const_iterator start,end;
275   start=ValuesPart.begin();
276   end=ValuesPart.end();
277
278   while (iterator != N)
279   {
280     regex_search(start,end, what, IntOrFloat);
281     iterator++;
282     start=what[0].second;
283     flags |= boost::match_prev_avail;
284     flags |= boost::match_not_bob;
285   }
286   return (atof((std::string(what[1].first,what[1].second)).c_str()));
287 }
288
289
290
291 std::string BrukerDataSet::GetTextValueN(std::string& file, int N)
292 {
293   return GetValuesPart(file);
294 }
295
296
297
298 int BrukerDataSet::GetKeywordNumberOfElements(std::string& file)
299 {
300   int NumberOfElements=1;
301   for (int i=1;i<=GetDimensionnality(file);i++)
302       NumberOfElements*=GetIntValueOfDimN(file, i);
303   return NumberOfElements;
304 }
305
306
307  
308 /**
309  * 
310 @fn bool BrukerDataSet::FillMap()
311 @brief This method fills the Bruker headermap with everything contained in the acqp file
312
313 The map is made of BrukerFieldData containing the keywords:
314 Datatype (string, int, double)
315 DimensionNumber: The number of Dimensions of the keyword-> 0 scalar, 1-> 1D-vector, 2-> 2D-Matrix, 3->3D-Matrix, ...
316 DimensionNumberValue: Gives the size of each dimension
317 DoubleValue: return a vector of values if they are of type double
318 IntValue: return a vector of values if they are of type int
319 StringValue: return a string if the values where not identified as a serie of numbers
320 NumberOfElements: Number of elements corresponding to the keyword given
321  * @return bool
322  */
323 bool BrukerDataSet::FillMap()
324 {
325   
326   std::string ValuesBuffer, Keyword,TempString, Substring;
327   int   i;
328   int KeywordNumber=0;
329   int PositionDebut=WholeHeader.find("##");
330   int PositionFin=PositionDebut+2; 
331   int PosRel;
332   BrukerFieldData data;
333   if (PositionFin>=WholeHeader.length()) 
334     return false;
335
336   while(PositionDebut!=std::string::npos)
337   {
338     PositionFin=WholeHeader.find("##",PositionDebut+2);
339     if (-1 == PositionFin) break ;
340     Substring=WholeHeader.substr (PositionDebut,PositionFin-PositionDebut-1);
341     PosRel=Substring.find("$$",0);
342     if (-1 != PosRel) Substring=Substring.substr (0,PosRel-1);
343
344
345     if (DEBUG) std::cout<<"Substring=[" << Substring << "]" <<std::endl;
346     
347     PositionDebut=PositionFin;
348     Keyword=GetKeyword(Substring);
349     if (DEBUG) std::cout<<"Keyword="<< Keyword <<std::endl;
350     data.DimensionNumber=GetDimensionnality(Substring);
351     if (DEBUG) std::cout<<"data.DimensionNumber="<< data.DimensionNumber <<std::endl;
352
353     data.DataType=GetContentType(Substring);
354     if (DEBUG) std::cout<<"data.DataType="<< data.DataType <<std::endl;
355     data.NumberOfElements=GetKeywordNumberOfElements(Substring);
356  if(data.DataType=="string") 
357       data.DimensionNumber=0;
358     if(data.DataType=="string") 
359       data.NumberOfElements=1;
360     if (DEBUG) std::cout<<"data.NumberOfElements="<< data.NumberOfElements <<std::endl;
361     
362     i=0;
363     while (i<=data.DimensionNumber)
364     {
365       data.DimensionNumberValue.push_back(GetIntValueOfDimN(Substring,i));
366       if (DEBUG) std::cout<<"data.DimensionNumberValue["<<i<<"]="<< data.DimensionNumberValue[i] <<std::endl;
367       i++;
368     }
369
370     if (DEBUG) std::cout<< "data= ";
371
372     for(i =1;i<=data.NumberOfElements;i++)
373     {
374
375       if (data.DataType=="int") 
376       { 
377         data.IntValue.push_back(GetIntValueN(Substring,i));
378         data.DoubleValue.push_back((double) GetIntValueN(Substring,i));
379         if (DEBUG) std::cout<< data.IntValue[i-1]<<" ";
380       }
381
382       if (data.DataType=="float") 
383       { 
384         data.DoubleValue.push_back(GetDoubleValueN(Substring,i));
385         if (DEBUG) std::cout<< data.DoubleValue[i-1]<<" ";
386       }
387     }
388
389     if (data.DataType=="string")
390     { 
391       data.StringValue.push_back(GetTextValueN(Substring,0));
392       if (DEBUG) std::cout<< "[" << data.StringValue[0]<<"] ";
393     }
394
395      if (DEBUG) std::cout<< std::endl  << "---- " <<std::endl;
396
397     BrukerDataSet::BrukerHeaderMap[ Keyword ] = data;
398     data.DimensionNumberValue.clear();
399     data.IntValue.clear();
400     data.DoubleValue.clear();
401     data.StringValue.clear();
402     data.DataType.clear();
403     KeywordNumber++;
404     //std::cout<<std::endl;
405   }
406   return true;
407 }
408
409
410 void BrukerDataSet::PrintKey(std::string & KeyWord)
411 {
412   int i;
413   if(!BrukerDataSet::CheckExistKeyword(KeyWord))
414   { 
415     std::cout<< "KeyWord = "<<KeyWord <<" doesn't exist !"<<std::endl;
416   }
417   else
418   {
419     std::cout<< "KeyWord = "<<KeyWord <<std::endl;    
420     BrukerDataSet::BrukerHeaderMap[ KeyWord ].PrintSelf();
421
422   }
423 }
424
425
426
427 void BrukerDataSet::PrintSelf()
428 {
429    BrukMapType::iterator it;
430    for (it=  BrukerHeaderMap.begin();
431          it !=  BrukerHeaderMap.end();
432        ++it )
433     {
434        std::cout << std::endl << "-----------------[" <<(*it).first << "]" << std::endl;
435        std::string a =  (*it).first;
436        PrintKey(a);
437     } 
438 }
439
440
441 bool BrukerDataSet::CheckExistKeyword(std::string &KeyWord)
442 {
443  BrukMapType::iterator element;
444   element = BrukerHeaderMap.find(KeyWord);
445   if (element != BrukerHeaderMap.end() )
446     return true;
447   return false;
448 }
449
450 bool BrukerDataSet::CheckExistKeyword(const char *KeyWord)
451 {
452 std::string temp(KeyWord);
453 BrukerDataSet::CheckExistKeyword(temp);
454     return true;
455 }
456
457
458 const BrukerFieldData& BrukerDataSet::GetFieldData(std::string & kw)
459 {
460    return BrukerHeaderMap[kw];
461 }
462
463 const BrukerFieldData& BrukerDataSet::GetFieldData(const char *kw)
464 {
465    std::string str_kw(kw);
466    return BrukerHeaderMap[str_kw];
467 }    
468
469
470 bool BrukerDataSet::Getkspace(std::string &FileToRead)
471 {
472   std::string GO_raw_data_format("GO_raw_data_format");
473   if (!CheckExistKeyword(GO_raw_data_format))
474     return false;
475   std::ifstream FID;
476
477   FID.open(FileToRead.c_str(), std::ios::binary);
478   if (FID.rdstate()==std::ios::failbit) 
479     return false;
480   FID.seekg (0, std::ios::end);
481   long length = FID.tellg();
482   FID.seekg (0, std::ios::beg);
483   long NumberOfValues;
484
485
486   if (GetTextValueN(GO_raw_data_format,1)=="GO_32BIT_SGN_INT") 
487     NumberOfValues=length/4;
488   if (GetTextValueN(GO_raw_data_format,1)=="GO_16BIT_SGN_INT") 
489     NumberOfValues=length/2;
490   if (GetTextValueN(GO_raw_data_format,1)=="GO_32BIT_FLOAT") 
491     NumberOfValues=length/4;
492
493   char * buffer;
494   buffer = new char[length];
495
496   FID.read (buffer,length);
497   FID.close();
498 //for (long i=0;i<NumberOfValues;i++) BrukerDataSet::WholeKspace.pushback(buffer[i]);
499   delete [] buffer;
500   return true;
501 }
502
503
504 std::vector< int > BrukerDataSet::GetLoopStructure() const
505 {
506    return LoopStructure;
507 }
508
509 /**
510     @fn bool BrukerDataSet::SetLoopStructure (const std::vector<int> & theValue )
511  * @brief this methods provide a way to inject a userdefined loop structure, be very aware that this method is not foolproof
512  * @param theValue 
513  * @return bool
514  */
515 bool BrukerDataSet::SetLoopStructure ( const std::vector<int> & theValue )
516 {
517    LoopStructure = theValue;
518    return true;
519 }
520
521
522 /**
523    @fn bool BrukerDataSet::SetLoopStructureOld ( )
524  * @brief method to set the default Bruker loopstructure (not yet able to deal with EPI, SPIRAL or spectroscopic experiments 
525  * @return bool
526  * @todo  implement multicoil version
527  */
528 bool BrukerDataSet::SetLoopStructureOld ()
529 {
530    LoopStructure.clear();
531 /*
532 \file brukerdataset.cpp
533 \fn bool BrukerDataSet::setGenericLoopStructure ( )
534 \brief sets the loop structure of a standard Bruker experiment
535
536 NR                               (Nbre de repetitions)
537    NILoop                        (Boucle eventuelle extra (Diffusion par exemple) si NI<>(NSLICES x NECHOES) cette boucle est a� NI/(NSLICES x NECHOES)
538                                  (Attention NILoop peut masquer plusieurs boucles imbriquees !!!!!)
539       ACQ_size[1..M]             (Codage suivant les autres dimensions)
540          NSLICES                 (Nombre de tranches)
541             ACQ_phase_factor     (Facteur turbo de la sequence)
542                ACQ_ns_list_size  (Nombre d'echos)
543                   ACQ_size[0]    (Ligne acq reelle)
544
545 */
546
547
548    std::string NRStr("NR");
549    std::string NIStr("NI");
550    std::string ACQ_sizeStr("ACQ_size");
551    std::string ACQ_phase_factorStr("ACQ_phase_factor");
552    std::string ACQ_ns_listStr("ACQ_ns_list");
553    std::string ACQ_ns_list_sizeStr("ACQ_ns_list_size");
554    std::string NSLICESStr("NSLICES");
555
556    int  i, temp;
557    std::vector<int> TempIntVect;
558    TempIntVect.clear();
559
560    if (! CheckExistKeyword(NRStr))              return false;
561    if (! CheckExistKeyword(NIStr))              return false;
562    if (! CheckExistKeyword(ACQ_sizeStr))        return false;
563    if (! CheckExistKeyword(ACQ_phase_factorStr))return false;
564    if (! CheckExistKeyword(ACQ_ns_list_sizeStr))return false;
565    if (! CheckExistKeyword(NSLICESStr))         return false;
566
567    TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_size" ].IntValue[0]);
568    TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[(std::string)  "ACQ_ns_list_size"].IntValue[0]);
569    TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[(std::string)  "ACQ_phase_factor"].IntValue[0]);
570    TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[(std::string)  "NSLICES"].IntValue[0]);
571    if (1<=BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_size" ].DimensionNumber ){
572       TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_size" ].IntValue[1]/BrukerDataSet::BrukerHeaderMap[(std::string)  "ACQ_phase_factor"].IntValue[0]);
573    if (2<=BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_size" ].DimensionNumber )
574    {
575       for(i=2;i<=BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_size" ].DimensionNumber;i++) 
576       {
577          TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_size" ].IntValue[i]);
578       }
579    }
580 }
581 // Ici, boucles additionnelles si elles existent regroupees en une seule
582 //temp=GetIntValueN(NIStr,1)/(GetIntValueN(NSLICESStr,1)*GetIntValueN(NECHOESStr,1));
583    temp=BrukerDataSet::BrukerHeaderMap[ (std::string)  "NI" ].IntValue[0]/(BrukerDataSet::BrukerHeaderMap[ (std::string)  "NSLICES" ].IntValue[0]*BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_ns_list_size" ].IntValue[0]);
584    if (1 < temp) 
585       TempIntVect.push_back(temp);
586 // fin des boucles cachees
587
588    TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string)  "NR" ].IntValue[0]);
589
590    LoopStructure=TempIntVect;
591    return true;
592 }
593
594
595 /**
596    @fn bool BrukerDataSet::SetLoopStructure ( )
597  * @brief method to set the default Bruker loopstructure (not yet able to deal with EPI, SPIRAL or spectroscopic experiments 
598  * @return bool
599    @todo  implement multicoil version
600  */
601 bool BrukerDataSet::SetLoopStructure (int dimension)
602 {
603    if (! SetInnerObjectLoopStructure(dimension)) return false;
604    if (! SetOuterObjectLoopStructure(dimension)) return false;
605    std::vector<int> Inner=GetInnerObjectLoopStructure();
606    std::vector<int> Outer=GetOuterObjectLoopStructure();
607    std::vector<int> TmpVect;
608    TmpVect=Inner;
609    TmpVect.insert(TmpVect.end(),Outer.begin(),Outer.end());
610    LoopStructure=TmpVect;
611    return true;
612 }
613
614 std::vector< std :: vector < int > > BrukerDataSet::GetBrukerObjectsLineList() const
615 {
616    return BrukerObjectsLineList;
617 }
618
619
620 bool BrukerDataSet::SetBrukerObjectsLineList ()
621 {
622
623    std::vector<int> Loop =GetLoopStructure();
624    int NumberOfLines, i,j;
625    NumberOfLines=1; 
626    i=1;
627
628    while (i<Loop.size())
629    {
630       NumberOfLines=NumberOfLines*Loop[i];
631       i++;
632    }
633
634    std::vector<int> TempVect  (Loop.size()-1,0);
635    std::vector<int> k  (Loop.size()-1,0);
636    std::vector<std::vector<int> > TempLineList (NumberOfLines,TempVect);
637
638    for (i=0;i<NumberOfLines;i++){
639       for (j=1;j<=Loop.size()-1;j++) {
640          if (k[j-1] >= Loop[j]) {
641             k[j-1]=0;
642             k[j]++;
643          }
644       }
645       for (j=1;j<=Loop.size()-1;j++) 
646          TempLineList[i][j-1]=k[j-1];
647       k[0]++;
648    }
649    BrukerObjectsLineList=TempLineList;
650    return true;
651 }
652
653
654 std::vector< std::vector < int > > BrukerDataSet::GetBrukerImageList() const
655 {
656    return BrukerImageList;
657 }
658
659
660 bool BrukerDataSet::SetBrukerImageList ()
661 {
662    if (LoopStructure.size()==0)
663       SetImageLoopStructure();
664
665    std::vector<int> Loop =GetImageLoopStructure();
666    int NumberOfLines, i,j;
667    NumberOfLines=1; 
668    i=1;
669
670    while (i<Loop.size())
671    {
672       NumberOfLines=NumberOfLines*Loop[i];
673       i++;
674    }
675
676    std::vector<int> TempVect (Loop.size()-1,0);
677    std::vector<int> k (Loop.size()-1,0);
678    std::vector<std::vector<int> > TempLineList (NumberOfLines,TempVect);
679
680    for (i=0;i<NumberOfLines;i++){
681       for (j=1;j<=Loop.size()-1;j++) {
682          if (k[j-1] >= Loop[j]) {
683             k[j-1]=0;
684             k[j]++;
685          }
686       }
687       for (j=1;j<=Loop.size()-1;j++) 
688          TempLineList[i][j-1]=k[j-1];
689       k[0]++;
690    }
691    BrukerImageList=TempLineList;
692    return true;
693 }
694
695
696
697 std::map<std::string, BrukerFieldData> BrukerDataSet::GetBrukerHeaderMap() const
698 {
699    return BrukerHeaderMap;
700 }
701
702
703
704
705 //std::map<std::string, BrukerFieldData> BrukerDataSet::GetBrukerHeaderMap() const
706 //{
707 //   return BrukerHeaderMap;
708 //}
709
710
711 bool BrukerDataSet::SetInnerObjectLoopStructure(int dimension)
712 {
713 /*
714  *
715  *
716  *      ACQ_size[1..M]                                  (Codage suivant les autres dimensions)
717                 NSLICES                                 (Nombre de tranches)
718                         ACQ_phase_factor                (Facteur turbo de la sequence)
719                                 ACQ_ns_list_size        (Nombre d'echos)
720                                         ACQ_size[0]     (Ligne acq reelle)
721
722 */
723
724    int  i, temp;
725    std::vector<int> TempIntVect;
726    TempIntVect.clear();
727
728
729    if (! CheckExistKeyword("ACQ_size"))        return false;
730    if (! CheckExistKeyword("ACQ_phase_factor"))return false;
731    if (! CheckExistKeyword("ACQ_ns_list_size"))return false;
732    if (! CheckExistKeyword("NSLICES"))         return false;
733
734
735 //std::cout<< "BrukerDataSet::BrukerHeaderMap[ (std::string)  ACQ_size ].IntValue[0]" <<BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_size" ].IntValue[0] << std::endl;
736    TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_size" ].IntValue[0]);
737 //std::cout<< "BrukerDataSet::BrukerHeaderMap[ (std::string)  ACQ_size ].IntValue[0]" <<BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_size" ].IntValue[0] << std::endl;
738    TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[(std::string)  "ACQ_ns_list_size"].IntValue[0]);
739 //std::cout<<"BrukerDataSet::BrukerHeaderMap[(std::string)  ACQ_ns_list_size].IntValue[0]" << BrukerDataSet::BrukerHeaderMap[(std::string)  "ACQ_ns_list_size"].IntValue[0] << std::endl;
740    TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[(std::string)  "ACQ_phase_factor"].IntValue[0]);
741 //std::cout<<"BrukerDataSet::BrukerHeaderMap[(std::string)  ACQ_phase_factor].IntValue[0]" <<  BrukerDataSet::BrukerHeaderMap[(std::string)  "ACQ_phase_factor"].IntValue[0]<< std::endl;
742    if(dimension > 1)
743    TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[(std::string)  "NSLICES"].IntValue[0]);
744 //std::cout << "BrukerDataSet::BrukerHeaderMap[(std::string)  NSLICES].IntValue[0]" << BrukerDataSet::BrukerHeaderMap[(std::string)  "NSLICES"].IntValue[0] << std::endl;
745    if (1<=BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_size" ].DimensionNumber )
746    {
747            if(dimension == 1)
748                    TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_size" ].IntValue[0]/BrukerDataSet::BrukerHeaderMap[(std::string)  "ACQ_phase_factor"].IntValue[0]);
749            else
750                         TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_size" ].IntValue[1]/BrukerDataSet::BrukerHeaderMap[(std::string)  "ACQ_phase_factor"].IntValue[0]);
751 //std::cout << "BrukerDataSet::BrukerHeaderMap[ (std::string)  ACQ_size ].IntValue[1]/BrukerDataSet::BrukerHeaderMap[(std::string)  ACQ_phase_factor].IntValue[0]" << BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_size"
752 //].IntValue[1]/BrukerDataSet::BrukerHeaderMap[(std::string)  "ACQ_phase_factor"].IntValue[0] << std::endl;
753       if (2<=BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_size" ].DimensionNumber )
754       {
755          for(i=2;i<=BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_size" ].DimensionNumber;i++) 
756          {
757             TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_size" ].IntValue[i]);
758          }
759       }
760    }
761
762    InnerObjectLoopStructure=TempIntVect;
763    return true;
764 }
765
766
767 std::vector< int > BrukerDataSet::GetInnerObjectLoopStructure() const
768 {
769    return InnerObjectLoopStructure;
770 }
771
772 std::vector< int > BrukerDataSet::GetOuterObjectLoopStructure() const
773 {
774    return OuterObjectLoopStructure;
775 }
776
777
778 bool BrukerDataSet::SetOuterObjectLoopStructure (int dimension)
779 {
780    OuterObjectLoopStructure.clear();
781    /*
782     NR      (Nbre de repetitions)
783     NILoop  (Boucle eventuelle extra (Diffusion par exemple) si NI<>(NSLICES x NECHOES) cette boucle est a� NI/(NSLICES x NECHOES)
784        (Attention NILoop peut masquer plusieurs boucles imbriquees !!!!!)
785   */
786    int  temp;
787    std::vector<int> TempIntVect;
788    TempIntVect.clear();
789    if (! CheckExistKeyword("NR")) return false;
790    if (! CheckExistKeyword("NI"))  return false;
791 // Ici, boucles additionnelles si elles existent regroupees en une seule
792 //temp=GetIntValueN(NIStr,1)/(GetIntValueN(NSLICESStr,1)*GetIntValueN(NECHOESStr,1));
793    if(dimension ==1)
794            temp=BrukerDataSet::BrukerHeaderMap[ (std::string)  "NI" ].IntValue[0]/(BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_ns_list_size" ].IntValue[0]);
795    else
796    temp=BrukerDataSet::BrukerHeaderMap[ (std::string)  "NI" ].IntValue[0]/(BrukerDataSet::BrukerHeaderMap[ (std::string)  "NSLICES" ].IntValue[0]*BrukerDataSet::BrukerHeaderMap[ (std::string)  "ACQ_ns_list_size" ].IntValue[0]);
797    if (1 < temp) 
798       TempIntVect.push_back(temp);
799 // fin des boucles cachees
800    TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string)  "NR" ].IntValue[0]);
801    OuterObjectLoopStructure=TempIntVect;
802    return true;
803 }
804
805
806 std::vector< int > BrukerDataSet::GetImageLoopStructure() const
807 {
808    return ImageLoopStructure;
809 }
810
811
812 bool BrukerDataSet::SetImageLoopStructure ( )
813 {
814    ImageLoopStructure.clear();
815    std::vector<int> TempIntVect1=GetInnerObjectLoopStructure();
816    std::vector<int> TempIntVect2=GetOuterObjectLoopStructure();
817    std::vector<int> TempIntVect3(TempIntVect1.size(),1);
818    std::vector<int> TempIntVect4;
819    TempIntVect3[1]=TempIntVect1[1];
820    TempIntVect3[3]=TempIntVect1[3];
821    TempIntVect4=TempIntVect3;
822    TempIntVect4.insert(TempIntVect4.end(),TempIntVect2.begin(),TempIntVect2.end());
823    ImageLoopStructure = TempIntVect4;
824    return true;
825 }
826