• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

beamtime/gsi-aug12/hd/go4/ROOTFORMAT/TRootConverterParam.cxx (r4864/r3215)

Go to the documentation of this file.
00001 /* Generated by Together */
00002 
00003 #include "TRootConverterParam.h"
00004 #include "TGo4Version.h"
00005 #if __GO4BUILDVERSION__ > 40502
00006    #include "go4iostream.h"
00007 #else
00008    #include "Riostream.h"
00009 #endif
00010 
00011 /***** Default values definition *****/
00012 #define OUTPUT_FILE_ENABLE     0
00013 #define OUTPUT_FILENAME    "testTree.root"
00014 #define ROOT_TREE_DISPLAY      0
00015 #define EVNT_BEF_RESET         5000
00016 #define GET4_DATA_IN_TREE      0
00017 #define TDC_REFERENCE         -1
00018 #define CHANNEL_TDC_REFERENCE -1
00019 #define CAEN_TDC_MODE          1
00020 #define CAEN_TDC_MUTLTI        0
00021 #define CAEN_TDC_GENERAL_ENA   0
00022 #define PMT_TDC               -1
00023 #define PMT_QDC               -1
00024 #define RPC_TDC_LEADING       -1
00025 #define RPC_TDC_LEADING       -1
00026 #define TRIGLOG_DATA_IN_TREE   0
00027 #define HODOSCOPE_DATA_IN_TREE 0
00028 #define HODOSCOPE_DEBUG_HISTO  0
00029 #define VFTX_DATA_IN_TREE      0
00030 #define VFTX_FULL_DATA_MODE    0
00031 #define SCALORMU_IN_TREE       0
00032 #define VFTX_ENABLE            0
00033 #define SLOW_CONTROL_IN_TREE   0
00034 #define NB_SLOW_CONTROL_CH     0
00035 /*************************************/
00036 
00037 //***********************************************************
00038 TRootConverterParam::TRootConverterParam() : TGo4Parameter()
00039 {
00040    uRootDisplay         = 0;  // No Online Change - Enable/Disable root tree display in GO4 interface
00041    uCleanOuputEnable    = 0;  // No Online Change - Enable/Disable the generation of a cleaned data output file
00042    uEventsUntilReset    = 0;  // When tree displayed but not saved, number of events in Tree before periodic reset
00043    sOutputFilename      = ""; // No Online Change - Filename for the output of the Cleanning/Unpack step
00044    uAddGet4DataInTree   = 0;  // No Online Change - Enable/Disable the Get4 data in the TTree root output
00045    iReferenceTdc        = -1; // Index of the Caen TDC containing the t0 hybrid reference time
00046    iReferenceChannel1   = -1; // Index of the channel containing the t0 hybrid reference time
00047    iReferenceChannel2   = -1; // Index of the channel containing the t0 hybrid reference time
00048    uCaenMode            =  0; // No Online Change - Caen Output mode
00049    uCaenMulti           =  0; // No Online Change - Enable/disable multi hits support for caen in general mode
00050    iPmtTdc              = -1; // Index of the Caen TDC containing the PMT data
00051    iPmtQdc              = -1; // Index of the Lecroy Qdc containing the PMT data
00052    iRpcTdcLeading       = -1; // Index of the Caen TDC containing the RPC leading  edge data
00053    iRpcTdcTrailing      = -1; // Index of the Caen TDC containing the RPC trailing edge data
00054    uTriglogInputInTree  = 0;  // No Online Change - Enable/Disable the triglog input scalers data in the TTree root output
00055    uHodoInputInTree     = 0;  // No Online Change - Enable/Disable the fiber hodoscope data in the TTree root output
00056    uHodoDebugHisto      = 0;  // No Online Change - Enable/Disable the fiber hodoscope ddebug histograms
00057    uVftxInTree          = 0;  // No Online Change - Enable/Disable the Vftx (Fpga TDC) data in the TTree root output
00058    uVftxFullDataMode    = 0;  // No Online Change - Enable/Disable the Vftx (Fpga TDC) data in the TTree root output
00059    uScalOrMuInTree      = 0;  // No Online Change - Enable/Disable the Scaler Or Multiplicity scaler data in TTree root output
00060    uSlowControlInTree   = 0;  // No Online Change - Enable/Disable inclusion of slow control data for HDRPC in Tree
00061    uNbSlowControlChan   = 0;  // No Online Change - Number of HV channels Slow Control to be saved in the tree
00062 }
00063 
00064 
00065 //***********************************************************
00066 TRootConverterParam::TRootConverterParam(const char* name) : TGo4Parameter(name)
00067 {
00068    uRootDisplay         = 0;  // No Online Change - Enable/Disable root tree display in GO4 interface
00069    uCleanOuputEnable    = 0;  // No Online Change - Enable/Disable the generation of a cleaned data output file
00070    uEventsUntilReset    = 0;  // When tree displayed but not saved, number of events in Tree before periodic reset
00071    sOutputFilename      = ""; // No Online Change - Filename for the output of the Cleanning/Unpack step
00072    uAddGet4DataInTree   = 0;  // No Online Change - Enable/Disable the Get4 data in the TTree root output
00073    iReferenceTdc        = -1; // Index of the Caen TDC containing the t0 hybrid reference time
00074    iReferenceChannel1   = -1; // Index of the channel containing the t0 hybrid reference time
00075    iReferenceChannel2   = -1; // Index of the channel containing the t0 hybrid reference time
00076    uCaenMode            =  0; // No Online Change - Caen Output mode
00077    uCaenMulti           =  0; // No Online Change - Enable/disable multi hits support for caen in general mode
00078    iPmtTdc              = -1; // Index of the Caen TDC containing the PMT data
00079    iPmtQdc              = -1; // Index of the Lecroy Qdc containing the PMT data
00080    iRpcTdcLeading       = -1; // Index of the Caen TDC containing the RPC leading  edge data
00081    iRpcTdcTrailing      = -1; // Index of the Caen TDC containing the RPC trailing edge data
00082    uTriglogInputInTree  = 0;  // No Online Change - Enable/Disable the triglog input scalers data in the TTree root output
00083    uHodoInputInTree     = 0;  // No Online Change - Enable/Disable the fiber hodoscope data in the TTree root output
00084    uHodoDebugHisto      = 0;  // No Online Change - Enable/Disable the fiber hodoscope ddebug histograms
00085    uVftxInTree          = 0;  // No Online Change - Enable/Disable the Vftx (Fpga TDC) data in the TTree root output
00086    uVftxFullDataMode    = 0;  // No Online Change - Enable/Disable the Vftx (Fpga TDC) data in the TTree root output
00087    uScalOrMuInTree      = 0;  // No Online Change - Enable/Disable the Scaler Or Multiplicity scaler data in TTree root output
00088    uSlowControlInTree   = 0;  // No Online Change - Enable/Disable inclusion of slow control data for HDRPC in Tree
00089    uNbSlowControlChan   = 0;  // No Online Change - Number of HV channels Slow Control to be saved in the tree
00090 
00091    ReadOptions();
00092    this->PrintOptions();
00093 }
00094 //***********************************************************
00095 
00096 TRootConverterParam::~TRootConverterParam()
00097 {
00098 }
00099 //-----------------------------------------------------------
00100 Bool_t TRootConverterParam::UpdateFrom(TGo4Parameter *pp)
00101 {
00102   if(pp->InheritsFrom("TRootConverterParam")) {
00103      TRootConverterParam * from = (TRootConverterParam *) pp;
00104      cout << "**** TRootConverterParam " << GetName() << " updated from source parameter" << endl;
00105   } else
00106      cout << "Wrong parameter object: " << pp->ClassName() << endl;
00107   return kTRUE;
00108 }
00109 
00110 Bool_t TRootConverterParam::ReadOptions()
00111 {// Loading default values for safety
00112    uRootDisplay         = ROOT_TREE_DISPLAY;
00113    uCleanOuputEnable    = OUTPUT_FILE_ENABLE;
00114    uEventsUntilReset    = EVNT_BEF_RESET;
00115    sOutputFilename      = OUTPUT_FILENAME;
00116    uAddGet4DataInTree   = GET4_DATA_IN_TREE;
00117    iReferenceTdc        = TDC_REFERENCE;
00118    iReferenceChannel1   = CHANNEL_TDC_REFERENCE;
00119    iReferenceChannel2   = CHANNEL_TDC_REFERENCE;
00120    uCaenMode            = CAEN_TDC_MODE;
00121    uCaenMulti           = CAEN_TDC_MUTLTI;
00122    for(UInt_t temp_index = 0; temp_index < MAX_HV_CHAN_SC; temp_index++)
00123       uGeneralCaenTdcEnabled[temp_index] = CAEN_TDC_GENERAL_ENA;
00124    iPmtTdc              = PMT_TDC;
00125    iPmtQdc              = PMT_QDC;
00126    iRpcTdcLeading       = RPC_TDC_LEADING;
00127    iRpcTdcTrailing      = RPC_TDC_LEADING;
00128    uTriglogInputInTree  = TRIGLOG_DATA_IN_TREE;
00129    uHodoInputInTree     = HODOSCOPE_DATA_IN_TREE;
00130    uHodoDebugHisto      = HODOSCOPE_DEBUG_HISTO;
00131    uVftxInTree          = VFTX_DATA_IN_TREE;
00132    uVftxFullDataMode    = VFTX_FULL_DATA_MODE;
00133    uScalOrMuInTree      = SCALORMU_IN_TREE;
00134    for(UInt_t temp_index = 0; temp_index < MAX_FPGA_TDC; temp_index++)
00135       uVftxEnabled[temp_index] = VFTX_ENABLE;
00136    uSlowControlInTree   = SLOW_CONTROL_IN_TREE;
00137    uNbSlowControlChan   = NB_SLOW_CONTROL_CH;
00138    for(UInt_t temp_index = 0; temp_index < MAX_HV_CHAN_SC; temp_index++)
00139    {
00140       sScInputNamePosI[temp_index] = "";
00141       sScOutputNamePosI[temp_index]= "";
00142       sScInputNamePosU[temp_index] = "";
00143       sScOutputNamePosU[temp_index]= "";
00144       sScInputNameNegI[temp_index] = "";
00145       sScOutputNameNegI[temp_index]= "";
00146       sScInputNameNegU[temp_index] = "";
00147       sScOutputNameNegU[temp_index]= "";
00148    } // for(UInt_t temp_index = 0; temp_index < MAX_HV_CHAN_SC; temp_index++)
00149 
00150    // Reading out parameters from the option file
00151    //~ fstream setupFile("./ROOTFORMAT/rootconv_options.txt", ios::in);
00152    fstream setupFile("./rootconv_options.txt", ios::in);
00153    if( setupFile.fail() == true)
00154    {
00155       cout<<"Error opening setup file rocget4_options.txt"<<endl;
00156       cout<<"=> Using default values!"<<endl;
00157    }
00158    else
00159    {
00160       TString line;
00161       line.ReadLine(setupFile, kFALSE);
00162       while( !setupFile.eof() )
00163       {
00164          if(line(0) == '#' || line(0) == '*')
00165          {
00166             //Comment
00167             ;
00168          }
00169          else if(line.Contains("disproot")==kTRUE)
00170          {
00171             uRootDisplay = ((TString)line(8,10)).Atoi();
00172          }
00173          else if(line.Contains("cleanoutp")==kTRUE)
00174          {
00175             uCleanOuputEnable = ((TString)line(10,10)).Atoi();
00176          }
00177          else if(line.Contains("nbevtrst")==kTRUE)
00178          {
00179             uEventsUntilReset = ((TString)line(8,10)).Atoi();
00180          }
00181          else if(line.Contains("cleanfile")==kTRUE)
00182          {
00183             sOutputFilename = line(10,120);
00184          }
00185          else if(line.Contains("get4intree")==kTRUE)
00186          {
00187             uAddGet4DataInTree = ((TString)line(11,10)).Atoi();
00188          }
00189          else if(line.Contains("indreftdc")==kTRUE)
00190          {
00191             iReferenceTdc = ((TString)line(10,10)).Atoi();
00192          }
00193          else if(line.Contains("charefone")==kTRUE)
00194          {
00195             iReferenceChannel1 = ((TString)line(10,10)).Atoi();
00196          }
00197          else if(line.Contains("chareftwo")==kTRUE)
00198          {
00199             iReferenceChannel2 = ((TString)line(10,10)).Atoi();
00200          }
00201          else if(line.Contains("caenmode")==kTRUE)
00202          {
00203             uCaenMode = ((TString)line(10,10)).Atoi();
00204          }
00205          else if(line.Contains("caenmulti")==kTRUE)
00206          {
00207             uCaenMulti = ((TString)line(10,10)).Atoi();
00208          }
00209          else if(line.Contains("caentdcena")==kTRUE)
00210          {
00211             line = line(11,39);
00212             if( 0 != line.Sizeof() )
00213             {
00214                for(UInt_t temp_index = 0; temp_index < MAX_1290 && 0 != line.Sizeof(); temp_index++)
00215                {
00216                   uGeneralCaenTdcEnabled[temp_index] = ((TString)line(0,3)).Atoi();
00217                   line = line(3,39);
00218                } // for(UInt_t temp_index = 0; temp_index < MAX_1290 && 0 != line.Sizeof(); temp_index++)
00219             } // if( 0 != line.Sizeof() )
00220          }
00221          else if(line.Contains("pmttdcind")==kTRUE)
00222          {
00223             iPmtTdc = ((TString)line(10,10)).Atoi();
00224          }
00225          else if(line.Contains("pmtqdcind")==kTRUE)
00226          {
00227             iPmtQdc = ((TString)line(10,10)).Atoi();
00228          }
00229          else if(line.Contains("rpctdclei")==kTRUE)
00230          {
00231             iRpcTdcLeading = ((TString)line(10,10)).Atoi();
00232          }
00233          else if(line.Contains("rpctdcfai")==kTRUE)
00234          {
00235             iRpcTdcTrailing = ((TString)line(10,10)).Atoi();
00236          }
00237          else if(line.Contains("trigintree")==kTRUE)
00238          {
00239             uTriglogInputInTree = ((TString)line(11,10)).Atoi();
00240          }
00241          else if(line.Contains("hodointree")==kTRUE)
00242          {
00243             uHodoInputInTree = ((TString)line(11,10)).Atoi();
00244          }
00245          else if(line.Contains("hodohisdeb")==kTRUE)
00246          {
00247             uHodoDebugHisto = ((TString)line(11,10)).Atoi();
00248          }
00249          else if(line.Contains("vftxintree")==kTRUE)
00250          {
00251             uVftxInTree = ((TString)line(11,10)).Atoi();
00252          }
00253          else if(line.Contains("vftxfullda")==kTRUE)
00254          {
00255             uVftxFullDataMode = ((TString)line(11,10)).Atoi();
00256          }
00257          else if(line.Contains("vftxenable")==kTRUE)
00258          {
00259             line = line(11,39);
00260             if( 0 != line.Sizeof() )
00261             {
00262                for(UInt_t temp_index = 0; temp_index < MAX_FPGA_TDC && 0 != line.Sizeof(); temp_index++)
00263                {
00264                   uVftxEnabled[temp_index] = ((TString)line(0,3)).Atoi();
00265                   line = line(3,39);
00266                } // for(UInt_t temp_index = 0; temp_index < MAX_1290 && 0 != line.Sizeof(); temp_index++)
00267             } // if( 0 != line.Sizeof() )
00268          }
00269          else if(line.Contains("scomintree")==kTRUE)
00270          {
00271             uScalOrMuInTree = ((TString)line(11,10)).Atoi();
00272          }
00273          else if(line.Contains("slcointree")==kTRUE)
00274          {
00275             uSlowControlInTree = ((TString)line(11,10)).Atoi();
00276          }
00277          else if(line.Contains("nbslowcoch")==kTRUE)
00278          {
00279             uNbSlowControlChan = ((TString)line(11,10)).Atoi();
00280             if( MAX_HV_CHAN_SC < uNbSlowControlChan)
00281                uNbSlowControlChan = MAX_HV_CHAN_SC;
00282          }
00283          else if(line.Contains("slowcontch")==kTRUE)
00284          {
00285             line = line(12,36);
00286             if( 0 != uNbSlowControlChan && 0 != line.Sizeof() )
00287             {
00288                UInt_t uChannelIndex = 0;
00289                for(UInt_t temp_index = 0; temp_index < uNbSlowControlChan && 0 != line.Sizeof(); temp_index++)
00290                {
00291                   uChannelIndex = ((TString)line(0,3)).Atoi();
00292 
00293                   uSlowControlChans[temp_index]= uChannelIndex;
00294                   sScInputNamePosI[temp_index] = Form("CBM:HV:A1526P:CH%d:imon", uChannelIndex);
00295                   sScOutputNamePosI[temp_index]= Form("I_PosHv_ch%d", uChannelIndex);
00296                   sScInputNamePosU[temp_index] = Form("CBM:HV:A1526P:CH%d:vmon", uChannelIndex);
00297                   sScOutputNamePosU[temp_index]= Form("U_PosHv_ch%d", uChannelIndex);
00298                   sScInputNameNegI[temp_index] = Form("CBM:HV:A1526N:CH%d:imon", uChannelIndex);
00299                   sScOutputNameNegI[temp_index]= Form("I_NegHv_ch%d", uChannelIndex);
00300                   sScInputNameNegU[temp_index] = Form("CBM:HV:A1526N:CH%d:vmon", uChannelIndex);
00301                   sScOutputNameNegU[temp_index]= Form("U_NegHv_ch%d", uChannelIndex);
00302 
00303                   line = line(3,36);
00304                } // for(UInt_t temp_index = 0; temp_index < uNbStrips && 0 != line.Sizeof(); temp_index++)
00305             } //  if( 0 != uNbSlowControlChan && 0 != line.Sizeof() )
00306             else if( 0 == line.Sizeof() )
00307                cout<<"Error: Some HV channel expected and empty string for exact indexes!"<<endl;
00308          } // else if(line.Contains("slowcontch")==kTRUE)
00309          
00310          line.ReadLine(setupFile, kFALSE);
00311       }
00312    }
00313    
00314    setupFile.close();
00315    
00316    return kTRUE;
00317 }
00318 Int_t TRootConverterParam::PrintOptions()
00319 {
00320    cout<<"******************* ROOT Tree converter parameters *********************"<<endl;
00321 //   cout<<"       Option values Root Converter Param"<<endl;
00322    if( uRootDisplay )
00323       cout<<"Clean data tree display in Go4:    ON "<<endl;
00324       else cout<<"Clean data tree display in Go4:    OFF"<<endl;
00325    if( uCleanOuputEnable )
00326    {
00327       cout<<"Output file for clean data tree:   ON "<<endl;
00328       cout<<"Output filename:                   "<<sOutputFilename<<endl;
00329    }
00330       else cout<<"Output file for clean data tree:   OFF"<<endl;
00331    if( uRootDisplay && 0 == uCleanOuputEnable )
00332       cout<<"Nb Events before periodic reset:   "<<uEventsUntilReset<<endl;
00333    if(1 == uRootDisplay || 1 == uCleanOuputEnable )
00334    {
00335       if( 1 == uAddGet4DataInTree )
00336          cout<<"GET4 data added to the TTree:       ON "<<endl;
00337          else cout<<"GET4 data added to the TTree:       OFF"<<endl;
00338       if( -1 != iPmtTdc || -1 != iPmtQdc )
00339       {
00340          cout<<"Caen TDC for PMT data:             "<<iPmtTdc<<endl;
00341          cout<<"Lecroy for PMT data:               "<<iPmtQdc<<endl;
00342       }
00343       if( 0 == uCaenMode)
00344       {
00345          cout<<"mode for CAEN data in tree:        COSY 2011 like "<<endl;
00346          if( -1 != iRpcTdcLeading || -1 != iRpcTdcTrailing )
00347          {
00348             cout<<"Caen TDC for RPC leading edge:    "<<iRpcTdcLeading<<endl;
00349             cout<<"Caen TDC for RPC trailing edge:   "<<iRpcTdcTrailing<<endl;
00350          }
00351          if( -1 != iReferenceTdc || -1 != iReferenceChannel1 || -1 != iReferenceChannel2)
00352          {
00353             cout<<"Caen TDC for t0 reference:        "<<iReferenceTdc<<endl;
00354             cout<<"1st Caen TDC Channel for t0 ref:  "<<iReferenceChannel1<<endl;
00355             cout<<"2nd Caen TDC Channel for t0 ref:  "<<iReferenceChannel2<<endl;
00356          }
00357       } // if( 0 == uCaenMode)
00358       else
00359       {
00360          cout<<"mode for CAEN data in tree:        General "<<endl;
00361          if( 1 == uCaenMulti )
00362             cout<<"CAEN multiple hits in TTree:       ON "<<endl;
00363             else cout<<"CAEN multiple hits in TTree:       OFF"<<endl;
00364 
00365          cout<<"Caen v1290 tdc index:      |-      ";
00366          for( Int_t iIndex1290 = 0; iIndex1290 < MAX_1290; iIndex1290++)
00367          {
00368             cout.width(2);
00369             cout<<iIndex1290<<" ";
00370          }
00371          cout<<endl<<"Added in Tree?             |->     ";
00372          for( Int_t iIndex1290 = 0; iIndex1290 < MAX_1290; iIndex1290++)
00373          {
00374             cout.width(2);
00375             cout<<uGeneralCaenTdcEnabled[iIndex1290]<<" ";
00376          }
00377          cout<<endl;
00378       } // else of if( 0 == uCaenMode) => general mode
00379       if( uTriglogInputInTree )
00380          cout<<"TrigLog data added to the TTree:   ON "<<endl;
00381          else cout<<"TrigLog data added to the TTree:   OFF"<<endl;
00382       if( uHodoInputInTree )
00383          cout<<"Hodoscope data added to the TTree: ON "<<endl;
00384          else cout<<"Hodoscope data added to the TTree: OFF"<<endl;
00385       if( uHodoDebugHisto )
00386          cout<<"Hodoscope debug histograms:        ON "<<endl;
00387          else cout<<"Hodoscope debug histograms:        OFF"<<endl;
00388       if( uVftxInTree )
00389       {
00390          cout<<"VFTX data added to the TTree:      ON "<<endl;
00391 
00392          if( uVftxFullDataMode )
00393          cout<<"VFTX data in tree:                 FULL = raw + calib "<<endl;
00394             else cout<<"VFTX data in tree:                 Only CALIB "<<endl;
00395 
00396          cout<<"VFTX tdc index:               |-      ";
00397          for( Int_t iIndexVftx = 0; iIndexVftx < MAX_FPGA_TDC; iIndexVftx++)
00398          {
00399             cout.width(2);
00400             cout<<iIndexVftx<<" ";
00401          }
00402          cout<<endl<<"Added in Tree?             |->     ";
00403          for( Int_t iIndexVftx = 0; iIndexVftx < MAX_FPGA_TDC; iIndexVftx++)
00404          {
00405             cout.width(2);
00406             cout<<uVftxEnabled[iIndexVftx]<<" ";
00407          }
00408          cout<<endl;
00409       }
00410          else cout<<"VFTX data added to the TTree:      OFF"<<endl;
00411       if( uScalOrMuInTree )
00412          cout<<"ScalOrMu scalers added to TTree:   ON "<<endl;
00413          else cout<<"ScalOrMu scalers added to TTree:   OFF"<<endl;
00414       if( uSlowControlInTree )
00415       {
00416          cout<<"HDRPC HV value added to the TTree: ON "<<endl;
00417          cout<<"Nb slow control HV channels saved:  "<<uNbSlowControlChan<<endl;
00418          cout<<"Index slow control HV channels:     ";
00419          for(UInt_t temp_index = 0; temp_index < uNbSlowControlChan; temp_index++)
00420             cout<<uSlowControlChans[temp_index]<<" ";
00421          cout<<endl;
00422 //         for(UInt_t temp_index = 0; temp_index < uNbSlowControlChan; temp_index++)
00423 //         {
00424 //            cout<<sScInputNamePosI[temp_index]<<" ";
00425 //            cout<<sScOutputNamePosI[temp_index]<<" ";
00426 //            cout<<sScInputNamePosU[temp_index]<<" ";
00427 //            cout<<sScOutputNamePosU[temp_index]<<" ";
00428 //            cout<<sScInputNameNegI[temp_index]<<" ";
00429 //            cout<<sScOutputNameNegI[temp_index]<<" ";
00430 //            cout<<sScInputNameNegU[temp_index]<<" ";
00431 //            cout<<sScOutputNameNegU[temp_index]<<" ";
00432 //            cout<<endl;
00433 //         }
00434       }
00435          else cout<<"HDRPC HV value added to the TTree: OFF"<<endl;
00436    }
00437    cout<<"************************************************************************"<<endl;
00438    
00439    return 0;
00440 }

Generated on Tue Dec 10 2013 04:52:18 for ROCsoft by  doxygen 1.7.1