void ReadData() { string InFile = "C:/Users/artripathi/Documents/TEST/SampleData.txt"; TStopwatch StopWatch; StopWatch.Reset(); StopWatch.Start(); Reader FileReader(InFile.c_str()); FileReader.SetDelimiter(','); FileReader.ReadFile(); StopWatch.Stop(); cout << "Total CPU Time = " << StopWatch.CpuTime() << " s\n"; cout << "Total Real Time = " << StopWatch.RealTime() << "s\n"; } /////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include class Reader { public: Reader(const char *InputFileName, const char *OutputFileName = 0, char Delimiter = ',', int NumGuessLines = 5); void ReadFile(); void SetDelimiter(char Delimiter) {fDelimiter = Delimiter;} private: std::string fInputFileName, fOutputFileName; char fDelimiter; vector fVarNames; vector fVarTypes; void ReadVariableNamesAndTypes(ifstream & in) ; // TPRegexp *rexp; TPRegexp rexp; int fNumGuessLines; // Number of lines to read to guess the var type }; ////////////////////////////////////////////////////////////////////// Reader::Reader(const char *InputFileName, const char *OutputFileName, char Delimiter, int NumGuessLines){ fDelimiter = Delimiter; if (InputFileName) { fInputFileName = InputFileName; } if (OutputFileName) { fOutputFileName = OutputFileName; } else { std::string::size_type loc = fInputFileName.find( '.',0) ; fOutputFileName = fInputFileName.substr(0,loc) + ".root"; std::cout << "No output file name is provided by the user\n"; std::cout << "Using Outfile name = " << fOutputFileName << std::endl; } fNumGuessLines = NumGuessLines; // Set up the regular expression to get tokens TString s = "([\(\)+-\\w\\s.:]+)"; s += fDelimiter; s += "?"; rexp = TPRegexp(s); } ///////////////////////////////////////////////////////////////////////////// void Reader::ReadFile(){ // First, make sure that input file name is provided if (fInputFileName.empty()) { std::cout << "No input file name specified. Exiting\n"; return 0; } // Print information about the output file, delimiter etc. std::cout << "Input will be read from file: " << fInputFileName << std::endl; std::cout << "Output will be written to the file: " << fOutputFileName << std::endl; std::cout << "Delimiter character = " << fDelimiter << std::endl; // Now, open the input file ifstream infile(fInputFileName.c_str()); if (!infile) { std::cout << "Error opening input file " << fInputFileName << std::endl; std::cout << "Exiting\n"; return 0; } else { std::cout << "Opened file " << fInputFileName << " for input " << std::endl; } // Read the variable names and types from the input file ReadVariableNamesAndTypes(infile) ; // Open a file for output TFile *fout = new TFile(fOutputFileName.c_str(),"RECREATE"); if (!fout) { std::cout << "Error opening output file " << fOutputFileName << std::endl; std::cout << "Exiting\n" ; return 0; } fout->cd(); // Book a tree TTree *tree = new TTree("tree"," "); // Vectors to keep the values of variables unsigned int nvars = fVarNames.size(); std::vector fCharValues(nvars); std::vector fFloatValues(nvars); // Assign branch addresses TString BranchDescription; for (unsigned int i = 0; i < nvars; i++) { BranchDescription = fVarNames[i]; if (toupper(fVarTypes[i]) == 'C') { BranchDescription += "/C"; tree->Branch(fVarNames[i], fCharValues[i].Data(), BranchDescription); } else { BranchDescription += "/F"; tree->Branch(fVarNames[i], &fFloatValues[i], BranchDescription); } } // end of loop over nvalues to create branches // Now loop through the file to fill the tree // Rewind the input stream to begining infile.seekg(0, std::ios::beg); if (!infile) { cout << "Error in infile" << endl; return 0; } TString s1, s2, s3; // Skip the first, header line. s1.ReadLine(infile); int LineCount = 0; while (1) { s1.ReadLine(infile); // cout << s1 << endl; Int_t index = 0; Int_t start = 0; while (1) { s2 = s1(rexp, start); s3 = s2.Strip(TString::kTrailing, fDelimiter); int len = s2.Length(); if (len <= 0) break; start += len; if (toupper(fVarTypes[index]) == 'F') { if (s3.IsNull() || s3.IsWhitespace() ) { fFloatValues[index] = -99.0; } else { fFloatValues[index] = s3.Atof(); } } else { fCharValues[index] = s3; } index++; } tree->Fill(); LineCount++; if (!infile) break; } tree->Write(); fout->Close(); delete fout; } ////////////////////////////////////////////////////////////////////////////// void Reader::ReadVariableNamesAndTypes(ifstream &in) { // Move to the begining of the stream in.seekg(0, std::ios::beg); // Parse the header and store the names and types in a vector TString s1, s2, s3; int LineCount = 0; while (1) { s1.ReadLine(in); Int_t index = 0; Int_t start = 0; while (1) { s2 = s1(rexp, start); s3 = s2.Strip(TString::kTrailing, fDelimiter); int len = s2.Length(); if (len <= 0) break; start += len; if (LineCount == 0) { fVarNames.push_back(s3); fVarTypes.push_back('F'); // To begin with set everything to floating point } else { if (!s3.IsFloat()) fVarTypes[index] = 'C'; } index++; } LineCount++; if (!in.good()) break; if (LineCount > fNumGuessLines) break; } cout << "Read " << LineCount << " lines " << endl; for (unsigned int i = 0; i < fVarNames.size(); i++) { cout << fVarNames[i] << " " << fVarTypes[i] << endl; } }