- Timestamp:
- 05/25/11 13:18:26 (14 years ago)
- Location:
- trunk/FACT++/src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/Fits.cc
r10780 r10814 82 82 //! @param fitsCounter a pointer to the integer keeping track of the opened FITS files 83 83 //! @param out a pointer to the MessageImp that should be used to log errors 84 // 85 void Fits::Open(const string& fileName, const string& tableName, FITS* file, int* fitsCounter, MessageImp* out)//ostream& out) 84 //! @param runNumber the runNumber for which this file is opened. -1 means nightly file. 85 // 86 void Fits::Open(const string& fileName, const string& tableName, FITS* file, int* fitsCounter, MessageImp* out, int runNumber) 86 87 { 87 88 // if (fMess) 88 89 // delete fMess; 89 90 // fMess = new MessageImp(out); 91 fRunNumber = runNumber; 90 92 fMess = out; 91 93 fFileName = fileName; -
trunk/FACT++/src/Fits.h
r10741 r10814 59 59 ///were to log the errors 60 60 MessageImp* fMess; 61 public: 61 public: 62 ///current run number being logged 63 int fRunNumber; 62 64 63 65 Fits() : fFile(NULL), … … 73 75 fFileName(""), 74 76 fNumOpenFitsFiles(NULL), 75 fMess(NULL) 77 fMess(NULL), 78 fRunNumber(-1) 76 79 {} 77 80 … … 91 94 92 95 ///Opens a FITS file 93 void Open(const string& fileName, const string& tableName, CCfits::FITS* file, int* fitsCounter, MessageImp* out );//ostream& out);96 void Open(const string& fileName, const string& tableName, CCfits::FITS* file, int* fitsCounter, MessageImp* out, int runNumber);//ostream& out); 94 97 95 98 ///Write one line of data. Use the given converter. -
trunk/FACT++/src/dataLogger.cc
r10780 r10814 78 78 79 79 //Dim structures 80 ///Distributes the writting statistics 80 81 struct DataLoggerStats { 81 82 long sizeWritten; … … 83 84 long writingRate; 84 85 }; 85 86 ///distributes the number of opened subscriptions and fits files 86 87 struct NumSubAndFitsType { 87 88 int numSubscriptions; 88 89 int numOpenFits; 89 90 }; 90 91 ///distributes which files were opened. 91 92 struct OpenFileToDim { 92 93 int code; 93 94 char fileName[FILENAME_MAX]; 95 }; 96 97 ///Run number record. Used to keep track of which run numbers are still active 98 struct RunNumberType { 99 ///the run number log file 100 ofstream* logFile; 101 ///the run number report file 102 ofstream* reportFile; 103 #ifdef HAVE_FITS 104 ///the run number group fits file 105 CCfits::FITS* runFitsFile; 106 #endif 107 ///the log filename 108 string logName; 109 ///the report filename 110 string reportName; 111 ///the actual run number 112 int runNumber; 113 ///the time at which the run number was received 114 Time time; 115 ///internal counter used for smart referencing 116 int* numCopies; 117 ///list of opened fits used to create the fits grouping when the run ends 118 map<string, vector<string> > openedFits; 119 ///default constructor 120 RunNumberType() 121 { 122 logFile = new ofstream(); 123 reportFile = new ofstream(); 124 #ifdef HAVE_FITS 125 runFitsFile = NULL; 126 #endif 127 runNumber = -1; 128 time = Time(0,0); 129 numCopies = new int(1); 130 } 131 ///default destructor 132 ~RunNumberType() 133 { 134 if (numCopies) 135 { 136 (*numCopies)--; 137 if (*numCopies < 1) 138 { 139 if (logFile) 140 { 141 if (logFile->is_open()) 142 logFile->close(); 143 delete logFile; 144 logFile = NULL; 145 } 146 if (reportFile) 147 { 148 if (reportFile->is_open()) 149 reportFile->close(); 150 delete reportFile; 151 reportFile = NULL; 152 } 153 #ifdef HAVE_FITS 154 if (runFitsFile) 155 { 156 delete runFitsFile; 157 runFitsFile = NULL; 158 } 159 #endif 160 delete numCopies; 161 numCopies = NULL; 162 } 163 } 164 } 165 ///copy operator 166 void operator = (const RunNumberType& other) 167 { 168 logFile = other.logFile; 169 reportFile = other.reportFile; 170 logName = other.logName; 171 reportName = other.reportName; 172 runNumber = other.runNumber; 173 time = other.time; 174 numCopies = other.numCopies; 175 #ifdef HAVE_FITS 176 runFitsFile = other.runFitsFile; 177 #endif 178 (*numCopies)++; 179 } 180 ///copy constructor 181 RunNumberType(const RunNumberType& other) 182 { 183 logFile = other.logFile; 184 reportFile = other.reportFile; 185 logName = other.logName; 186 reportName = other.reportName; 187 runNumber = other.runNumber; 188 time = other.time; 189 numCopies = other.numCopies; 190 #ifdef HAVE_FITS 191 runFitsFile = other.runFitsFile; 192 #endif 193 (*numCopies)++; 194 } 195 196 }; 197 ///Dim subscription type. Stores all the relevant info to handle a Dim subscription 198 struct SubscriptionType 199 { 200 #ifdef HAVE_FITS 201 ///Nightly FITS output file 202 Fits nightlyFile; 203 ///run-specific FITS output file 204 Fits runFile; 205 #endif 206 ///the actual dimInfo pointer 207 DimStampedInfo* dimInfo; 208 ///the converter for outputting the data according to the format 209 Converter* fConv; 210 ///internal counter used for smart referencing 211 int* numCopies; 212 ///the current run number used by this subscription 213 int runNumber; 214 ///copy operator 215 void operator = (const SubscriptionType& other) 216 { 217 #ifdef HAVE_FITS 218 nightlyFile = other.nightlyFile; 219 runFile = other.runFile; 220 #endif 221 dimInfo = other.dimInfo; 222 numCopies = other.numCopies; 223 fConv = other.fConv; 224 runNumber = other.runNumber; 225 (*numCopies)++; 226 } 227 ///copy constructor 228 SubscriptionType(const SubscriptionType& other) 229 { 230 #ifdef HAVE_FITS 231 nightlyFile = other.nightlyFile; 232 runFile = other.runFile; 233 #endif 234 dimInfo = other.dimInfo; 235 numCopies = other.numCopies; 236 fConv = other.fConv; 237 runNumber = other.runNumber; 238 (*numCopies)++; 239 } 240 ///Dim info constructor 241 SubscriptionType(DimStampedInfo* info) 242 { 243 dimInfo = info; 244 fConv = NULL; 245 runNumber = -1; 246 numCopies = new int(1); 247 } 248 ///default constructor 249 SubscriptionType() 250 { 251 dimInfo = NULL; 252 fConv = NULL; 253 runNumber = -1; 254 numCopies = new int(1); 255 } 256 ///default destructor 257 ~SubscriptionType() 258 { 259 if (numCopies) 260 (*numCopies)--; 261 if (numCopies) 262 if (*numCopies < 1) 263 { 264 if (dimInfo) 265 delete dimInfo; 266 #ifdef HAVE_FITS 267 if (nightlyFile.IsOpen()) 268 nightlyFile.Close(); 269 if (runFile.IsOpen()) 270 runFile.Close(); 271 #endif 272 if (numCopies) 273 delete numCopies; 274 delete fConv; 275 fConv = NULL; 276 dimInfo = NULL; 277 numCopies = NULL; 278 } 279 } 94 280 }; 95 281 … … 109 295 DataLogger(ostream &out); 110 296 ~DataLogger(); 111 297 298 bool SetConfiguration(Configuration& conf); 299 112 300 private: 113 //Define all the data structure specific to the DataLogger here 114 /// ofstream for the NightlyLogfile 301 /************************************************ 302 * MEMBER VARIABLES 303 ************************************************/ 304 /// ofstream for the NightlyLogfile 115 305 ofstream fNightlyLogFile; 116 /// ofstream for the run-specific Log file117 ofstream fRunLogFile;118 119 306 /// ofstream for the Nightly report file 120 307 ofstream fNightlyReportFile; 121 /// ofstream for the run-specific report file122 ofstream fRunReportFile;123 308 /// base path of the Nightlyfile 124 string fNightlyFile Name;309 string fNightlyFilePath; 125 310 ///base path of the run file 126 string fRunFile Name;127 ///run number (-1 means no run number specified)128 int fRunNumber;311 string fRunFilePath; 312 ///run numbers 313 list<RunNumberType> fRunNumber; 129 314 ///previous run number. to check if changed while logging 130 315 int fPreviousRunNumber; … … 133 318 ///Modified Julian Date 134 319 double fMjD; 320 ///for obtaining the name of the existing services 321 ServiceList fServiceList; 322 typedef map<const string, map<string, SubscriptionType> > SubscriptionsListType; 323 ///All the services to which we have subscribed to, sorted by server name. 324 SubscriptionsListType fServiceSubscriptions; 325 ///full name of the nightly log file 326 string fFullNightlyLogFileName; 327 ///full name of the nightly report file 328 string fFullNightlyReportFileName; 329 135 330 public: 331 /*************************************************** 332 * STATIC COMMAND NAMES 333 ***************************************************/ 136 334 ///Define all the static names 137 335 static const char* fConfigDay; … … 152 350 static const char* fStartStopNumSubsAndFits; 153 351 private: 352 /*************************************************** 353 * DIM INFO HANDLER 354 ***************************************************/ 154 355 //overloading of DIM's infoHandler function 155 356 void infoHandler(); 156 157 ///for obtaining the name of the existing services 158 ServiceList fServiceList; 159 160 ///A std pair to store both the DimInfo pointer and the corresponding outputted fits file 161 struct SubscriptionType 162 { 163 #ifdef HAVE_FITS 164 ///Nightly FITS output file 165 Fits nightlyFile; 166 ///run-specific FITS output file 167 Fits runFile; 168 #endif 169 ///the actual dimInfo pointer 170 DimStampedInfo* dimInfo; 171 ///the converter for outputting the data according to the format 172 Converter* fConv; 173 ///the number of existing handlers to this structure. 174 ///This is required otherwise I MUST handle the deleting of dimInfo outside from the destructor 175 int* numCopies; 176 void operator = (const SubscriptionType& other) 177 { 178 #ifdef HAVE_FITS 179 nightlyFile = other.nightlyFile; 180 runFile = other.runFile; 181 #endif 182 dimInfo = other.dimInfo; 183 numCopies = other.numCopies; 184 fConv = other.fConv; 185 (*numCopies)++; 186 } 187 SubscriptionType(const SubscriptionType& other) 188 { 189 #ifdef HAVE_FITS 190 nightlyFile = other.nightlyFile; 191 runFile = other.runFile; 192 #endif 193 dimInfo = other.dimInfo; 194 numCopies = other.numCopies; 195 fConv = other.fConv; 196 (*numCopies)++; 197 } 198 SubscriptionType(DimStampedInfo* info) 199 { 200 dimInfo = info; 201 fConv = NULL; 202 numCopies = new int(1); 203 } 204 SubscriptionType() 205 { 206 dimInfo = NULL; 207 fConv = NULL; 208 numCopies = new int(1); 209 } 210 ~SubscriptionType() 211 { 212 if (numCopies) 213 (*numCopies)--; 214 if (numCopies) 215 if (*numCopies < 1) 216 { 217 if (dimInfo) 218 delete dimInfo; 219 #ifdef HAVE_FITS 220 if (nightlyFile.IsOpen()) 221 nightlyFile.Close(); 222 if (runFile.IsOpen()) 223 runFile.Close(); 224 #endif 225 if (numCopies) 226 delete numCopies; 227 delete fConv; 228 fConv = NULL; 229 dimInfo = NULL; 230 numCopies = NULL; 231 } 232 } 233 }; 234 typedef map<const string, map<string, SubscriptionType> > SubscriptionsListType; 235 ///All the services to which we have subscribed to, sorted by server name. 236 SubscriptionsListType fServiceSubscriptions; 237 357 358 /*************************************************** 359 * TRANSITION FUNCTIONS 360 ***************************************************/ 238 361 ///Reporting method for the services info received 239 362 void ReportPlease(DimInfo* I, SubscriptionType& sub); 240 241 363 ///Configuration of the nightly file path 242 364 int ConfigureNightlyFileName(const Event& evt); … … 246 368 int ConfigureRunNumber(const Event& evt); 247 369 ///logging method for the messages 248 int LogMessagePlease(const Event& evt); 370 // int LogMessagePlease(const Event& evt); 249 371 ///print the current state of the dataLogger 250 372 int PrintStatePlease(const Event& evt); … … 263 385 #ifdef HAVE_FITS 264 386 ///Open fits files 265 void OpenFITSFilesPlease(SubscriptionType& sub );387 void OpenFITSFilesPlease(SubscriptionType& sub, RunNumberType* cRunNumber); 266 388 ///Write data to FITS files 267 389 void WriteToFITS(SubscriptionType& sub); 268 390 ///Allocate the buffers required for fits 269 391 void AllocateFITSBuffers(SubscriptionType& sub); 270 ///FITS file for runs grouping. only one, hence dealt with in the dataLogger itself271 CCfits::FITS* fRunFitsFile;272 392 #endif//has_fits 273 public: 274 ///checks with fServiceList whether or not the services got updated 275 bool CheckForServicesUpdate(); 276 277 private: 393 394 /*************************************** 395 * DIM SERVICES PROVIDED BY THE DATA LOGGER 396 ***************************************/ 278 397 ///monitoring notification loop 279 398 void ServicesMonitoring(); 399 inline void NotifyOpenedFile(string name, int type, DimDescribedService* service); 280 400 ///services notification thread 281 401 boost::thread fMonitoringThread; 282 402 ///end of the monitoring 283 403 bool fContinueMonitoring; 284 /// required for accurate monitoring404 ///stores the size of each file that is or was open 285 405 map<string, long> fFileSizesMap; 286 string fFullNightlyLogFileName; 287 string fFullNightlyReportFileName; 288 string fFullRunLogFileName; 289 string fFullRunReportFileName; 406 ///total size of the opened files BEFORE they were opened by the logger 290 407 long fBaseSizeNightly; 291 408 long fPreviousSize; … … 296 413 DimDescribedService* fNumSubAndFits; 297 414 NumSubAndFitsType fNumSubAndFitsData; 298 299 inline void NotifyOpenedFile(string name, int type, DimDescribedService* service);300 301 public: 302 bool SetConfiguration(Configuration& conf);303 304 private: 415 ///Small function for calculating the total size written so far 416 void calculateTotalSizeWritten(DataLoggerStats& statVar, bool& shouldWarn, bool isPrinting); 417 418 /*************************************************** 419 * DATA LOGGER's CONFIGURATION STUFF 420 ***************************************************/ 421 ///black/white listing 305 422 set<string> fBlackList; 306 423 set<string> fWhiteList; 424 ///list of services to be grouped 307 425 set<string> fGrouping; 426 ///configuration flags 308 427 bool fHasBlackList; 309 428 bool fHasWhiteList; … … 317 436 int SetOpenedFilesOnOff(const Event& evt); 318 437 int SetNumSubsAndFitsOnOff(const Event& evt); 438 319 439 ///boolean to prevent DIM update while desctructing the dataLogger 320 440 bool fDestructing; 321 322 ///Small function for calculating the total size written so far 323 void calculateTotalSizeWritten(DataLoggerStats& statVar, bool& shouldWarn, bool isPrinting); 324 441 /*************************************************** 442 * UTILITIES 443 ***************************************************/ 325 444 ///vectors to keep track of opened Fits files, for grouping purposes. 326 //This cannot be done otherwise, as services may disapear before the files are nicely closed. Hence which files were opened must be remembered.327 map<string, vector<string> > fOpenedRunFits;328 445 map<string, vector<string> > fOpenedNightlyFits; 329 void CreateFitsGrouping(bool runGroup); 446 ///creates a group fits file based on a list of files to be grouped 447 void CreateFitsGrouping(map<string, vector<string> >& filesToGroup, int runNumber); 448 ///Open the relevant text files related to a particular run 449 int OpenRunFile(RunNumberType& run); 450 ///add a new run number 451 void AddNewRunNumber(int newRun, Time time); 452 ///removes the oldest run number, and close the relevant files. 453 void RemoveOldestRunNumber(); 454 ///checks with fServiceList whether or not the services got updated 455 bool CheckForServicesUpdate(); 330 456 }; //DataLogger 331 457 458 // -------------------------------------------------------------------------- 459 // 460 //! Removes the oldest run number and closes the fits files that should be closed 461 //! Also creates the fits grouping file 462 // 463 void DataLogger::RemoveOldestRunNumber() 464 { 465 if (fDebugIsOn) 466 { 467 stringstream str; 468 str << "Removing run number " << fRunNumber.front().runNumber; 469 Debug(str.str()); 470 } 471 CreateFitsGrouping(fRunNumber.front().openedFits, fRunNumber.front().runNumber); 472 //crawl through the subscriptions to see if there are still corresponding fits files opened. 473 SubscriptionsListType::iterator x; 474 map<string, SubscriptionType>::iterator y; 475 for (x=fServiceSubscriptions.begin(); x != fServiceSubscriptions.end(); x++) 476 for (y=x->second.begin(); y != x->second.end(); y++) 477 if (y->second.runFile.fRunNumber == fRunNumber.front().runNumber && y->second.runFile.IsOpen()) 478 { 479 if (fDebugIsOn) 480 { 481 stringstream str; 482 str << "Closing Fits run file " << y->second.runFile.fFileName; 483 Debug(str.str()); 484 } 485 y->second.runFile.Close(); 486 } 487 //if a grouping file is on, decrease the number of opened fits manually 488 if (fRunNumber.front().runFitsFile) 489 (fNumSubAndFitsData.numOpenFits)--; 490 //remove the entry 491 fRunNumber.pop_front(); 492 } 493 494 // -------------------------------------------------------------------------- 495 // 496 //! Calculate the total number of written bytes since the logger was started 497 //! @param statVar the data structure that should be updated 498 //! @param shouldWarn whether or not error messages should be outputted 499 //! @param isPrinting whether this function was called from the PRINT command or not. If so, displays relevant information 500 // 332 501 void DataLogger::calculateTotalSizeWritten(DataLoggerStats& statVar, bool& shouldWarn, bool isPrinting) 333 502 { … … 377 546 fFileSizesMap[fFullNightlyReportFileName] = st.st_size; 378 547 } 379 if (fRunLogFile.is_open()) 380 { 381 stat(fFullRunLogFileName.c_str(), &st); 382 fFileSizesMap[fFullRunLogFileName] = st.st_size; 383 } 384 if (fRunReportFile.is_open()) 385 { 386 stat(fFullRunReportFileName.c_str(), &st); 387 fFileSizesMap[fFullRunReportFileName] = st.st_size; 548 for (list<RunNumberType>::iterator it = fRunNumber.begin(); it != fRunNumber.end(); it++) 549 { 550 if (it->reportFile->is_open()) 551 { 552 stat(it->reportName.c_str(), &st); 553 fFileSizesMap[it->reportName] = st.st_size; 554 } 555 if (it->logFile->is_open()) 556 { 557 stat(it->logName.c_str(), &st); 558 fFileSizesMap[it->logName] = st.st_size; 559 } 388 560 } 389 561 struct statvfs vfs; 390 if (!statvfs(fNightlyFile Name.c_str(), &vfs))562 if (!statvfs(fNightlyFilePath.c_str(), &vfs)) 391 563 { 392 564 statVar.freeSpace = vfs.f_bsize*vfs.f_bavail; … … 397 569 ostringstream str; 398 570 str.str(""); 399 str << "Unable to retrieve stats for " << fNightlyFile Name<< ". Reason: " << strerror(errno) << " [" << errno << "]";571 str << "Unable to retrieve stats for " << fNightlyFilePath << ". Reason: " << strerror(errno) << " [" << errno << "]"; 400 572 if (!shouldWarn) 401 573 Error(str); … … 429 601 const char* DataLogger::fStartStopNumSubsAndFits = "NUM_SUBS_SRVC"; 430 602 603 // -------------------------------------------------------------------------- 604 // 605 //! Monitor the number of opened files and total size written, and distributes this data through a Dim service 606 // 607 // 431 608 void DataLogger::ServicesMonitoring() 432 609 { … … 437 614 438 615 struct statvfs vfs; 439 if (!statvfs(fNightlyFile Name.c_str(), &vfs))616 if (!statvfs(fNightlyFilePath.c_str(), &vfs)) 440 617 statVar.freeSpace = vfs.f_bsize*vfs.f_bavail; 441 618 else … … 448 625 while (fContinueMonitoring) 449 626 { 627 //check if some run number entries can be deleted 628 while (fRunNumber.size() > 1 && (Time() - fRunNumber.front().time) > boost::posix_time::time_duration(0,0,10,0)) 629 { 630 RemoveOldestRunNumber(); 631 } 450 632 if (fStatsPeriodDuration == 0.0f) 451 633 { … … 477 659 } 478 660 479 480 661 // -------------------------------------------------------------------------- 481 662 // … … 490 671 dis_disable_padding(); 491 672 //initialize member data 492 fNightlyFileName = "."; 493 fRunFileName = "."; 494 fRunNumber = -1; 495 fPreviousRunNumber = fRunNumber; 496 #ifdef HAVE_FITS 497 fRunFitsFile = NULL; 498 #endif 499 500 //Give a name to this machine's specific states 501 AddStateName(kSM_NightlyOpen, "NightlyFileOpen", "The summary files for the night are open."); 502 AddStateName(kSM_WaitingRun, "WaitForRun", "The summary files for the night are open and we wait for a run to be started."); 503 AddStateName(kSM_Logging, "Logging", "The summary files for the night and the files for a single run are open."); 504 AddStateName(kSM_BadNightlyConfig, "ErrNightlyFolder", "The folder for the nighly summary files is invalid."); 505 AddStateName(kSM_BadRunConfig, "ErrRunFolder", "The folder for the run files is invalid."); 506 507 /*Add the possible transitions for this machine*/ 508 AddEvent(kSM_NightlyOpen, fTransStart, kSM_Ready, kSM_BadNightlyConfig) 509 (boost::bind(&DataLogger::StartPlease, this)) 510 ("Start the nightly logging. Nightly file location must be specified already"); 511 512 AddEvent(kSM_Ready, fTransStop, kSM_NightlyOpen, kSM_WaitingRun, kSM_Logging) 513 (boost::bind(&DataLogger::GoToReadyPlease, this)) 514 ("Stop all data logging, close all files."); 515 516 AddEvent(kSM_Logging, fTransStartRun, kSM_WaitingRun, kSM_BadRunConfig) 517 (boost::bind(&DataLogger::StartRunPlease, this)) 518 ("Start the run logging. Run file location must be specified already."); 519 520 AddEvent(kSM_WaitingRun, fTransStopRun, kSM_Logging) 521 (boost::bind(&DataLogger::StopRunPlease, this)) 522 ("Wait for a run to be started, open run-files as soon as a run number arrives."); 523 524 AddEvent(kSM_Ready, fTransReset, kSM_Error, kSM_BadNightlyConfig, kSM_BadRunConfig, kSM_Error) 525 (boost::bind(&DataLogger::GoToReadyPlease, this)) 526 ("Transition to exit error states. Closes the nightly file if already opened."); 527 528 AddEvent(kSM_WaitingRun, fTransWait, kSM_NightlyOpen) 529 (boost::bind(&DataLogger::NightlyToWaitRunPlease, this)); 530 531 /*Add the possible configurations for this machine*/ 532 AddEvent(fConfigDay, "C", kSM_Ready, kSM_BadNightlyConfig) 533 (boost::bind(&DataLogger::ConfigureNightlyFileName, this, _1)) 534 ("Configure the folder for the nightly files." 535 "|Path[string]:Absolute or relative path name where the nightly files should be stored."); 536 537 AddEvent(fConfigRun, "C", kSM_Ready, kSM_BadNightlyConfig, kSM_NightlyOpen, kSM_WaitingRun, kSM_BadRunConfig) 538 (boost::bind(&DataLogger::ConfigureRunFileName, this, _1)) 539 ("Configure the folder for the run files." 540 "|Path[string]:Absolute or relative path name where the run files should be stored."); 541 542 AddEvent(fConfigRunNumber, "I", kSM_Ready, kSM_BadNightlyConfig, kSM_NightlyOpen, kSM_WaitingRun, kSM_BadRunConfig) 543 (boost::bind(&DataLogger::ConfigureRunNumber, this, _1)) 544 ("configure the run number. cannot be done in logging state"); 673 fNightlyFilePath = "."; 674 fRunFilePath = "."; 675 676 //Give a name to this machine's specific states 677 AddStateName(kSM_NightlyOpen, "NightlyFileOpen", "The summary files for the night are open."); 678 AddStateName(kSM_WaitingRun, "WaitForRun", "The summary files for the night are open and we wait for a run to be started."); 679 AddStateName(kSM_Logging, "Logging", "The summary files for the night and the files for a single run are open."); 680 AddStateName(kSM_BadNightlyConfig, "ErrNightlyFolder", "The folder for the nighly summary files is invalid."); 681 AddStateName(kSM_BadRunConfig, "ErrRunFolder", "The folder for the run files is invalid."); 682 683 /*Add the possible transitions for this machine*/ 684 AddEvent(kSM_NightlyOpen, fTransStart, kSM_Ready, kSM_BadNightlyConfig) 685 (boost::bind(&DataLogger::StartPlease, this)) 686 ("Start the nightly logging. Nightly file location must be specified already"); 687 688 AddEvent(kSM_Ready, fTransStop, kSM_NightlyOpen, kSM_WaitingRun, kSM_Logging) 689 (boost::bind(&DataLogger::GoToReadyPlease, this)) 690 ("Stop all data logging, close all files."); 691 692 AddEvent(kSM_Logging, fTransStartRun, kSM_WaitingRun, kSM_BadRunConfig) 693 (boost::bind(&DataLogger::StartRunPlease, this)) 694 ("Start the run logging. Run file location must be specified already."); 695 696 AddEvent(kSM_WaitingRun, fTransStopRun, kSM_Logging) 697 (boost::bind(&DataLogger::StopRunPlease, this)) 698 ("Wait for a run to be started, open run-files as soon as a run number arrives."); 699 700 AddEvent(kSM_Ready, fTransReset, kSM_Error, kSM_BadNightlyConfig, kSM_BadRunConfig, kSM_Error) 701 (boost::bind(&DataLogger::GoToReadyPlease, this)) 702 ("Transition to exit error states. Closes the nightly file if already opened."); 703 704 AddEvent(kSM_WaitingRun, fTransWait, kSM_NightlyOpen) 705 (boost::bind(&DataLogger::NightlyToWaitRunPlease, this)); 706 707 /*Add the possible configurations for this machine*/ 708 AddEvent(fConfigDay, "C", kSM_Ready, kSM_BadNightlyConfig) 709 (boost::bind(&DataLogger::ConfigureNightlyFileName, this, _1)) 710 ("Configure the folder for the nightly files." 711 "|Path[string]:Absolute or relative path name where the nightly files should be stored."); 712 713 AddEvent(fConfigRun, "C", kSM_Ready, kSM_BadNightlyConfig, kSM_NightlyOpen, kSM_WaitingRun, kSM_BadRunConfig) 714 (boost::bind(&DataLogger::ConfigureRunFileName, this, _1)) 715 ("Configure the folder for the run files." 716 "|Path[string]:Absolute or relative path name where the run files should be stored."); 717 718 AddEvent(fConfigRunNumber, "I", kSM_Ready, kSM_NightlyOpen, kSM_WaitingRun, kSM_BadRunConfig, kSM_Logging) 719 (boost::bind(&DataLogger::ConfigureRunNumber, this, _1)) 720 ("configure the run number. cannot be done in logging state"); 545 721 546 722 //Provide a logging command … … 549 725 //is already done in StateMachineImp.cc 550 726 //Thus I'll simply add a configuration, which I will treat as the logging command 551 AddEvent(fConfigLog, "C", kSM_NightlyOpen, kSM_Logging, kSM_WaitingRun, kSM_BadRunConfig)552 (boost::bind(&DataLogger::LogMessagePlease, this, _1))553 ("Log a single message to the log-files."554 "|Message[string]:Message to be logged.");727 // AddEvent(fConfigLog, "C", kSM_NightlyOpen, kSM_Logging, kSM_WaitingRun, kSM_BadRunConfig) 728 // (boost::bind(&DataLogger::LogMessagePlease, this, _1)) 729 // ("Log a single message to the log-files." 730 // "|Message[string]:Message to be logged."); 555 731 556 732 //Provide a print command … … 768 944 if (fNightlyReportFile.is_open()) 769 945 fNightlyReportFile.close(); 770 if (fRunLogFile.is_open()) 771 fRunLogFile.close(); 772 if (fRunReportFile.is_open()) 773 fRunReportFile.close(); 946 //check if some run number entries can be deleted 947 while (fRunNumber.size() > 0) 948 { 949 RemoveOldestRunNumber(); 950 } 951 774 952 delete fOpenedNightlyFiles; 775 953 delete fOpenedRunFiles; 776 954 delete fNumSubAndFits; 777 #ifdef HAVE_FITS 778 if (fRunFitsFile != NULL) 779 delete fRunFitsFile; 780 fRunFitsFile = NULL; 781 #endif 955 782 956 if (fDebugIsOn) 783 957 { … … 847 1021 CheckForRunNumber(I); 848 1022 849 if (fPreviousRunNumber != fRunNumber)850 {//run number has changed. close and reopen run files.851 StopRunPlease();852 StartRunPlease();853 fPreviousRunNumber = fRunNumber;854 }855 856 1023 ReportPlease(I, y->second); 857 1024 858 1025 } 859 1026 // -------------------------------------------------------------------------- 1027 // 1028 //! Open the text files associated with the given run number 1029 //! @param run the run number to be dealt with 1030 // 1031 int DataLogger::OpenRunFile(RunNumberType& run) 1032 { 1033 ostringstream sRun; 1034 sRun << run.runNumber; 1035 run.logName = fRunFilePath + '/' + sRun.str() + ".log"; 1036 if (run.logFile->is_open()) 1037 { 1038 stringstream str; 1039 str << "Log file " << run.logName << " was already open when trying to open it in OpenRunFile"; 1040 Error(str.str()); 1041 return -1; 1042 } 1043 1044 run.logFile->open(run.logName.c_str(), ios_base::out | ios_base::app); 1045 if (errno != 0) 1046 { 1047 ostringstream str; 1048 str << "Unable to open run Log " << run.logName << ". Reason: " << strerror(errno) << " [" << errno << "]"; 1049 Error(str); 1050 } 1051 //open report file 1052 run.reportName = fRunFilePath + '/' + sRun.str() + ".rep"; 1053 if (run.reportFile->is_open()) 1054 { 1055 stringstream str; 1056 str << "Report file " << run.reportName << " was already open when trying to open it in OpenRunFile"; 1057 Error(str.str()); 1058 return -1; 1059 } 1060 run.reportFile->open(run.reportName.c_str(), ios_base::out | ios_base::app); 1061 if (errno != 0) 1062 { 1063 ostringstream str; 1064 str << "Unable to open run report " << run.reportName << ". Reason: " << strerror(errno) << " [" << errno << "]"; 1065 Error(str); 1066 } 1067 1068 if (!run.logFile->is_open() || !run.reportFile->is_open()) 1069 { 1070 ostringstream str; 1071 str << "Something went wrong while openning nightly files " << run.logName << " and " << run.reportName; 1072 Error(str.str()); 1073 return -1; 1074 } 1075 //get the size of the newly opened file. 1076 struct stat st; 1077 fBaseSizeRun = 0; 1078 if (fFileSizesMap.find(run.logName) == fFileSizesMap.end()) 1079 { 1080 stat(run.logName.c_str(), &st); 1081 if (errno != 0) 1082 { 1083 ostringstream str; 1084 str << "Unable to stat " << run.logName << ". Reason: " << strerror(errno) << " [" << errno << "]"; 1085 Error(str); 1086 } 1087 else 1088 fBaseSizeRun += st.st_size; 1089 fFileSizesMap[run.logName] = 0; 1090 } 1091 if (fFileSizesMap.find(run.reportName) == fFileSizesMap.end()) 1092 { 1093 stat(run.reportName.c_str(), &st); 1094 if (errno != 0) 1095 { 1096 ostringstream str; 1097 str << "Unable to stat " << run.reportName << ". Reason: " << strerror(errno) << " [" << errno << "]"; 1098 Error(str); 1099 } 1100 else 1101 fBaseSizeRun += st.st_size; 1102 fFileSizesMap[run.reportName] = 0; 1103 } 1104 string actualTargetDir; 1105 if (fRunFilePath == ".") 1106 { 1107 char currentPath[FILENAME_MAX]; 1108 if (!getcwd(currentPath, sizeof(currentPath))) 1109 { 1110 if (errno != 0) 1111 { 1112 ostringstream str; 1113 str << "Unable to retrieve the current path" << ". Reason: " << strerror(errno) << " [" << errno << "]"; 1114 Error(str); 1115 } 1116 } 1117 actualTargetDir = currentPath; 1118 } 1119 else 1120 { 1121 actualTargetDir = fRunFilePath; 1122 } 1123 //TODO this notification scheme might be messed up now.... fix it ! 1124 NotifyOpenedFile(actualTargetDir + '/' + sRun.str(), 3, fOpenedRunFiles); 1125 run.openedFits.clear(); 1126 return 0; 1127 } 1128 // -------------------------------------------------------------------------- 1129 // 1130 //! Add a new active run number 1131 //! @param newRun the new run number 1132 //! @param time the time at which the new run number was issued 1133 // 1134 void DataLogger::AddNewRunNumber(int newRun, Time time) 1135 { 1136 if (fDebugIsOn) 1137 { 1138 stringstream str; 1139 str << "Adding new run number " << newRun << " that was issued on " << time; 1140 Debug(str.str()); 1141 } 1142 //Add new run number to run number list 1143 fRunNumber.push_back(RunNumberType()); 1144 fRunNumber.back().runNumber = newRun; 1145 fRunNumber.back().time = time; 1146 if (GetCurrentState() != kSM_Logging) 1147 return; 1148 //open the log and report files 1149 OpenRunFile(fRunNumber.back()); 1150 } 860 1151 // -------------------------------------------------------------------------- 861 1152 // … … 869 1160 if (strstr(I->getName(), fRunNumberInfo) != NULL) 870 1161 {//assumes that the run number is an integer 871 fRunNumber = I->getInt();1162 AddNewRunNumber(I->getInt(), Time(I->getTimestamp(), I->getTimestampMillisecs()*1000)); 872 1163 ostringstream str; 873 str << "New run number is " << fRunNumber ;1164 str << "New run number is " << fRunNumber.back().runNumber; 874 1165 Message(str.str()); 875 1166 } … … 912 1203 } 913 1204 } 914 915 1205 //construct the header 916 1206 ostringstream header; … … 918 1208 fQuality = I->getQuality(); 919 1209 fMjD = cTime.Mjd(); 1210 1211 //figure out which run file should be used 1212 ofstream* targetRunFile = NULL; 1213 RunNumberType* cRunNumber = NULL; 1214 if (GetCurrentState() == kSM_Logging) 1215 { 1216 list<RunNumberType>::reverse_iterator rit; 1217 for (rit=fRunNumber.rbegin(); rit != fRunNumber.rend(); rit++) 1218 { 1219 if (rit->time < cTime) //this is the run number that we want to use 1220 { 1221 //Find something better to convert iterator to pointer than the ugly line below.... 1222 cRunNumber = &(*rit); 1223 sub.runNumber = rit->runNumber; 1224 targetRunFile = isItaReport ? rit->reportFile : rit->logFile; 1225 break; 1226 } 1227 } 1228 if (rit == fRunNumber.rend() && fRunNumber.size() != 0) 1229 { 1230 stringstream str; 1231 str << "Could not find an appropriate run number for info coming at time: " << cTime; 1232 Error(str.str()); 1233 Error("Active run numbers: "); 1234 for (rit=fRunNumber.rbegin(); rit != fRunNumber.rend(); rit++) 1235 { 1236 str.str(""); 1237 str << rit->runNumber; 1238 Error(str.str()); 1239 } 1240 } 1241 } 920 1242 921 1243 if (isItaReport) … … 972 1294 } 973 1295 //write entry to run-report 974 if ( fRunReportFile.is_open())1296 if (targetRunFile && targetRunFile->is_open()) 975 1297 { 976 1298 if (fDebugIsOn) … … 980 1302 Debug(str.str()); 981 1303 } 982 fRunReportFile << header.str() << text << endl;983 if (! fRunReportFile.good())1304 *targetRunFile << header.str() << text << endl; 1305 if (!targetRunFile->good()) 984 1306 { 985 1307 Error("An error occured while writing to the run report file. Closing it."); 986 if ( fRunReportFile.is_open())987 fRunReportFile.close();1308 if (targetRunFile->is_open()) 1309 targetRunFile->close(); 988 1310 } 989 1311 } … … 993 1315 string n = I->getName(); 994 1316 ostringstream msg; 995 msg << n << ": " << I->getString(); //n.substr(0, n.find_first_of('/')) << ": " << I->getString();1317 msg << n << ": " << I->getString(); 996 1318 997 1319 if (fNightlyLogFile.is_open()) … … 1012 1334 } 1013 1335 } 1014 if ( fRunLogFile.is_open())1336 if (targetRunFile && targetRunFile->is_open()) 1015 1337 { 1016 1338 if (fDebugIsOn) … … 1020 1342 Debug(str.str()); 1021 1343 } 1022 MessageImp runMess( fRunLogFile);1344 MessageImp runMess(*targetRunFile); 1023 1345 runMess.Write(cTime, msg.str().c_str(), fQuality); 1024 if (! fRunLogFile.good())1346 if (!targetRunFile->good()) 1025 1347 { 1026 1348 Error("An error occured while writing to the run log file. Closing it."); 1027 if ( fRunLogFile.is_open())1028 fRunLogFile.close();1349 if (targetRunFile->is_open()) 1350 targetRunFile->close(); 1029 1351 } 1030 1352 } … … 1034 1356 if (isItaReport) 1035 1357 { 1036 if (!sub.nightlyFile.IsOpen() || !sub.runFile.IsOpen() )1037 OpenFITSFilesPlease(sub );1358 if (!sub.nightlyFile.IsOpen() || !sub.runFile.IsOpen() || sub.runNumber != sub.runFile.fRunNumber) 1359 OpenFITSFilesPlease(sub, cRunNumber); 1038 1360 WriteToFITS(sub); 1039 1361 } … … 1045 1367 // 1046 1368 //! write messages to logs. 1369 /* 1047 1370 //! @param evt 1048 1371 //! the current event to log … … 1138 1461 } 1139 1462 return GetCurrentState(); 1140 } 1463 }*/ 1141 1464 // -------------------------------------------------------------------------- 1142 1465 // … … 1154 1477 //print the path configuration 1155 1478 string actualTargetDir; 1156 if (fNightlyFile Name== ".")1479 if (fNightlyFilePath == ".") 1157 1480 { 1158 1481 char currentPath[FILENAME_MAX]; … … 1161 1484 } 1162 1485 else 1163 actualTargetDir = fNightlyFile Name;1486 actualTargetDir = fNightlyFilePath; 1164 1487 Message("Nightly Path: " + actualTargetDir); 1165 if (fRunFile Name== ".")1488 if (fRunFilePath == ".") 1166 1489 { 1167 1490 char currentPath[FILENAME_MAX]; … … 1170 1493 } 1171 1494 else 1172 actualTargetDir = fRunFile Name;1495 actualTargetDir = fRunFilePath; 1173 1496 Message("Run Path: " + actualTargetDir); 1174 1497 ostringstream str; 1175 str << "Run Number: " << fRunNumber; 1498 str << "Active Run Numbers: ";//<< fRunNumber; 1499 for (list<RunNumberType>::iterator it=fRunNumber.begin(); it!=fRunNumber.end(); it++) 1500 str << "\n" << it->runNumber; 1176 1501 Message(str.str()); 1177 1502 Message("----------- OPENED FILES ----------------"); … … 1185 1510 else 1186 1511 Message("Nightly Report.....CLOSED"); 1187 if (fRunLogFile.is_open()) 1188 Message("Run Log..............OPEN"); 1189 else 1190 Message("Run Log............CLOSED"); 1191 if (fRunReportFile.is_open()) 1192 Message("Run Report...........OPEN"); 1193 else 1194 Message("Run Report.........CLOSED"); 1512 for (list<RunNumberType>::iterator it=fRunNumber.begin(); it!=fRunNumber.end(); it++) 1513 { 1514 if (it->logFile->is_open()) 1515 Message("Run Log " + it->logName + " is OPEN"); 1516 else 1517 Message("Run Log " + it->logName + " is CLOSED"); 1518 if (it->reportFile->is_open()) 1519 Message("Run Report " + it->reportName + " is OPEN"); 1520 else 1521 Message("Run Report " + it->reportName + " CLOSED"); 1522 } 1195 1523 bool statWarning = false; 1196 1524 DataLoggerStats statVar; … … 1365 1693 if (evt.GetText() != NULL) 1366 1694 { 1367 fNightlyFile Name= string(evt.GetText());1368 Message("New Nightly folder specified: " + fNightlyFile Name);1695 fNightlyFilePath = string(evt.GetText()); 1696 Message("New Nightly folder specified: " + fNightlyFilePath); 1369 1697 } 1370 1698 else … … 1384 1712 if (evt.GetText() != NULL) 1385 1713 { 1386 fRunFile Name= string(evt.GetText());1387 Message("New Run folder specified: " + fRunFile Name);1714 fRunFilePath = string(evt.GetText()); 1715 Message("New Run folder specified: " + fRunFilePath); 1388 1716 } 1389 1717 else … … 1401 1729 int DataLogger::ConfigureRunNumber(const Event& evt) 1402 1730 { 1403 fRunNumber = evt.GetInt(); 1731 AddNewRunNumber(evt.GetInt(), evt.GetTime()); 1732 // fRunNumber = evt.GetInt(); 1404 1733 ostringstream str; 1405 str << "The new run number is: " << fRunNumber ;1734 str << "The new run number is: " << fRunNumber.back().runNumber; 1406 1735 Message(str.str()); 1407 1736 return GetCurrentState(); … … 1452 1781 sTime << time.Y() << "_" << time.M() << "_" << time.D(); 1453 1782 1454 fFullNightlyLogFileName = fNightlyFile Name + '/' + sTime.str() + ".log";1783 fFullNightlyLogFileName = fNightlyFilePath + '/' + sTime.str() + ".log"; 1455 1784 fNightlyLogFile.open(fFullNightlyLogFileName.c_str(), ios_base::out | ios_base::app); 1456 1785 if (errno != 0) … … 1460 1789 Error(str); 1461 1790 } 1462 fFullNightlyReportFileName = fNightlyFile Name+ '/' + sTime.str() + ".rep";1791 fFullNightlyReportFileName = fNightlyFilePath + '/' + sTime.str() + ".rep"; 1463 1792 fNightlyReportFile.open(fFullNightlyReportFileName.c_str(), ios_base::out | ios_base::app); 1464 1793 if (errno != 0) … … 1487 1816 //notify that files were opened 1488 1817 string actualTargetDir; 1489 if (fNightlyFile Name== ".")1818 if (fNightlyFilePath == ".") 1490 1819 { 1491 1820 char currentPath[FILENAME_MAX]; … … 1503 1832 else 1504 1833 { 1505 actualTargetDir = fNightlyFile Name;1834 actualTargetDir = fNightlyFilePath; 1506 1835 } 1507 1836 //notify that a new file has been opened. … … 1519 1848 //! @param sub 1520 1849 //! the current DimInfo subscription being examined 1521 void DataLogger::OpenFITSFilesPlease(SubscriptionType& sub )1850 void DataLogger::OpenFITSFilesPlease(SubscriptionType& sub, RunNumberType* cRunNumber) 1522 1851 { 1523 1852 string serviceName(sub.dimInfo->getName()); 1524 //we must check if we should group this service subscription to a single fits file before we replace the / by _ 1853 //if run number has changed, reopen a new fits file with the correct run number. 1854 if (sub.runFile.IsOpen() && sub.runFile.fRunNumber != sub.runNumber) 1855 { 1856 if (fDebugIsOn) 1857 { 1858 Debug("Run number changed. Closing " + sub.runFile.fFileName); 1859 } 1860 sub.runFile.Close(); 1861 } 1862 //we must check if we should group this service subscription to a single fits file before we replace the / by _ 1525 1863 bool hasGrouping = false; 1526 1864 if (!sub.runFile.IsOpen() && (GetCurrentState() == kSM_Logging)) … … 1535 1873 } 1536 1874 } 1875 hasGrouping = true; 1537 1876 for (unsigned int i=0;i<serviceName.size(); i++) 1538 1877 { … … 1550 1889 { 1551 1890 string fileNameOnly = sTime.str() + '_' + serviceName + ".fits"; 1552 string partialName = fNightlyFile Name+ '/' + fileNameOnly;1891 string partialName = fNightlyFilePath + '/' + fileNameOnly; 1553 1892 AllocateFITSBuffers(sub); 1554 1893 //get the size of the file we're about to open … … 1562 1901 fOpenedNightlyFits[fileNameOnly].push_back(serviceName); 1563 1902 } 1564 sub.nightlyFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits, this );//Out());1903 sub.nightlyFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits, this, -1);//Out()); 1565 1904 1566 1905 //notify the opening 1567 1906 string actualTargetDir; 1568 if (fNightlyFile Name== ".")1907 if (fNightlyFilePath == ".") 1569 1908 { 1570 1909 char currentPath[FILENAME_MAX]; … … 1574 1913 else 1575 1914 { 1576 actualTargetDir = fNightlyFile Name;1915 actualTargetDir = fNightlyFilePath; 1577 1916 } 1578 1917 NotifyOpenedFile(actualTargetDir + '/' + sTime.str(), 7, fOpenedNightlyFiles); … … 1586 1925 } 1587 1926 } 1588 if (!sub.runFile.IsOpen() && (GetCurrentState() == kSM_Logging)) 1927 //to the actual file open 1928 if (!sub.runFile.IsOpen() && (GetCurrentState() == kSM_Logging) && sub.runNumber != -1) 1589 1929 {//buffer for the run file have already been allocated when doing the Nightly file 1590 1930 ostringstream sRun; 1591 sRun << fRunNumber;1931 sRun << sub.runNumber; 1592 1932 string fileNameOnly; 1593 1933 string partialName; … … 1596 1936 { 1597 1937 fileNameOnly = sRun.str() + "_group.fits"; 1598 partialName = fRunFile Name+ '/' + fileNameOnly;1938 partialName = fRunFilePath + '/' + fileNameOnly; 1599 1939 } 1600 1940 else 1601 1941 { 1602 1942 fileNameOnly = sRun.str() + '_' + serviceName + ".fits"; 1603 partialName = fRunFile Name+ '/' + fileNameOnly;1943 partialName = fRunFilePath + '/' + fileNameOnly; 1604 1944 } 1605 1945 //get the size of the file we're about to open … … 1612 1952 fBaseSizeRun = 0; 1613 1953 fFileSizesMap[partialName] = 0; 1614 fOpenedRunFits[fileNameOnly].push_back(serviceName);1954 cRunNumber->openedFits[fileNameOnly].push_back(serviceName); 1615 1955 } 1616 1956 else … … 1620 1960 //and reopened again. Unlikely to happen, but well it may 1621 1961 bool found = false; 1622 for (vector<string>::iterator it= fOpenedRunFits[fileNameOnly].begin(); it!=fOpenedRunFits[fileNameOnly].end(); it++)1962 for (vector<string>::iterator it=cRunNumber->openedFits[fileNameOnly].begin(); it!=cRunNumber->openedFits[fileNameOnly].end(); it++) 1623 1963 if (*it == serviceName) 1624 1964 { … … 1627 1967 } 1628 1968 if (!found) 1629 fOpenedRunFits[fileNameOnly].push_back(serviceName); 1630 } 1631 if (hasGrouping && fRunFitsFile == NULL) 1969 cRunNumber->openedFits[fileNameOnly].push_back(serviceName); 1970 } 1971 1972 if (hasGrouping && cRunNumber->runFitsFile == NULL) 1632 1973 try 1633 1974 { 1634 fRunFitsFile = new CCfits::FITS(partialName, CCfits::RWmode::Write);1975 cRunNumber->runFitsFile = new CCfits::FITS(partialName, CCfits::RWmode::Write); 1635 1976 (fNumSubAndFitsData.numOpenFits)++; 1636 1977 } … … 1640 1981 str << "Could not open FITS Run file " << partialName << " reason: " << e.message(); 1641 1982 Error(str); 1642 fRunFitsFile = NULL;1983 cRunNumber->runFitsFile = NULL; 1643 1984 } 1644 1985 1645 1986 string actualTargetDir; 1646 if (fRunFile Name== ".")1987 if (fRunFilePath == ".") 1647 1988 { 1648 1989 char currentPath[FILENAME_MAX]; … … 1652 1993 else 1653 1994 { 1654 actualTargetDir = fRunFile Name;1995 actualTargetDir = fRunFilePath; 1655 1996 } 1656 1997 NotifyOpenedFile(actualTargetDir + '/' + sRun.str(), 7, fOpenedRunFiles);// + '_' + serviceName, 4); 1657 1998 if (hasGrouping) 1658 sub.runFile.Open(partialName, serviceName, fRunFitsFile, &fNumSubAndFitsData.numOpenFits, this);//Out());1999 sub.runFile.Open(partialName, serviceName, cRunNumber->runFitsFile, &fNumSubAndFitsData.numOpenFits, this, sub.runNumber);//Out()); 1659 2000 else 1660 sub.runFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits, this );//Out());2001 sub.runFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits, this, sub.runNumber);//Out()); 1661 2002 1662 2003 if (fNumSubAndFitsIsOn) … … 1671 2012 } 1672 2013 // -------------------------------------------------------------------------- 2014 // 2015 //! Allocates the required memory for a given pair of fits files (nightly and run) 2016 //! @param sub the subscription of interest. 1673 2017 // 1674 2018 void DataLogger::AllocateFITSBuffers(SubscriptionType& sub) … … 1785 2129 Debug("Starting Run Logging..."); 1786 2130 } 1787 //attempt to open run file with current parameters 1788 // if (fRunNumber == -1) 1789 // return kSM_BadRunConfig; 1790 ostringstream sRun; 1791 sRun << fRunNumber; 1792 fFullRunLogFileName = fRunFileName + '/' + sRun.str() + ".log"; 1793 fRunLogFile.open(fFullRunLogFileName.c_str(), ios_base::out | ios_base::app); //maybe should be app instead of ate 1794 if (errno != 0) 1795 { 1796 ostringstream str; 1797 str << "Unable to open run Log " << fFullRunLogFileName << ". Reason: " << strerror(errno) << " [" << errno << "]"; 1798 Error(str); 1799 } 1800 fFullRunReportFileName = fRunFileName + '/' + sRun.str() + ".rep"; 1801 fRunReportFile.open(fFullRunReportFileName.c_str(), ios_base::out | ios_base::app); 1802 if (errno != 0) 1803 { 1804 ostringstream str; 1805 str << "Unable to open run report " << fFullRunReportFileName << ". Reason: " << strerror(errno) << " [" << errno << "]"; 1806 Error(str); 1807 } 1808 1809 if (!fRunLogFile.is_open() || !fRunReportFile.is_open()) 1810 { 1811 ostringstream str; 1812 str << "Something went wrong while openning nightly files " << fFullRunLogFileName << " and " << fFullRunReportFileName; 1813 Error(str.str()); 1814 return kSM_BadRunConfig; 1815 } 1816 //get the size of the newly opened file. 1817 struct stat st; 1818 fBaseSizeRun = 0; 1819 if (fFileSizesMap.find(fFullRunLogFileName) == fFileSizesMap.end()) 1820 { 1821 stat(fFullRunLogFileName.c_str(), &st); 1822 if (errno != 0) 1823 { 1824 ostringstream str; 1825 str << "Unable to stat " << fFullRunLogFileName << ". Reason: " << strerror(errno) << " [" << errno << "]"; 1826 Error(str); 1827 } 1828 else 1829 fBaseSizeRun += st.st_size; 1830 fFileSizesMap[fFullRunLogFileName] = 0; 1831 } 1832 if (fFileSizesMap.find(fFullRunReportFileName) == fFileSizesMap.end()) 1833 { 1834 stat(fFullRunReportFileName.c_str(), &st); 1835 if (errno != 0) 1836 { 1837 ostringstream str; 1838 str << "Unable to stat " << fFullRunReportFileName << ". Reason: " << strerror(errno) << " [" << errno << "]"; 1839 Error(str); 1840 } 1841 else 1842 fBaseSizeRun += st.st_size; 1843 fFileSizesMap[fFullRunReportFileName] = 0; 1844 } 1845 string actualTargetDir; 1846 if (fRunFileName == ".") 1847 { 1848 char currentPath[FILENAME_MAX]; 1849 if (!getcwd(currentPath, sizeof(currentPath))) 1850 { 1851 if (errno != 0) 1852 { 1853 ostringstream str; 1854 str << "Unable to retrieve the current path" << ". Reason: " << strerror(errno) << " [" << errno << "]"; 1855 Error(str); 1856 } 1857 } 1858 actualTargetDir = currentPath; 1859 } 1860 else 1861 { 1862 actualTargetDir = fRunFileName; 1863 } 1864 NotifyOpenedFile(actualTargetDir + '/' + sRun.str(), 3, fOpenedRunFiles); 1865 1866 fOpenedRunFits.clear(); 2131 //open all the relevant run-files. i.e. all the files associated with run numbers. 2132 for (list<RunNumberType>::iterator it=fRunNumber.begin(); it != fRunNumber.end(); it++) 2133 OpenRunFile(*it); 1867 2134 1868 2135 return kSM_Logging; 1869 2136 } 2137 1870 2138 #ifdef HAVE_FITS 1871 void DataLogger::CreateFitsGrouping(bool runGroup) 2139 // -------------------------------------------------------------------------- 2140 // 2141 //! Create a fits group file with all the run-fits that were written (either daily or run) 2142 //! @param filesToGroup a map of filenames mapping to table names to be grouped (i.e. a 2143 //! single file can contain several tables to group 2144 //! @param runNumber the run number that should be used for grouping. -1 means nightly group 2145 // 2146 void DataLogger::CreateFitsGrouping(map<string, vector<string> > & filesToGroup, int runNumber) 1872 2147 { 1873 2148 if (fDebugIsOn) … … 1875 2150 ostringstream str; 1876 2151 str << "Creating fits group for "; 1877 if (run Group)2152 if (runNumber != -1) 1878 2153 str << "run files"; 1879 2154 else … … 1883 2158 //create the FITS group corresponding to the ending run. 1884 2159 CCfits::FITS* groupFile; 1885 map<string, vector<string> >& filesToGroup = runGroup? fOpenedRunFits : fOpenedNightlyFits;1886 2160 unsigned int numFilesToGroup = 0; 1887 2161 for (map<string, vector<string> >::iterator it=filesToGroup.begin(); it != filesToGroup.end(); it++) … … 1901 2175 } 1902 2176 ostringstream groupName; 1903 if (run Group)1904 { 1905 groupName << fRunFile Name << '/' << fRunNumber << ".fits";2177 if (runNumber != -1) 2178 { 2179 groupName << fRunFilePath << '/' << runNumber << ".fits"; 1906 2180 } 1907 2181 else … … 1911 2185 sTime << time.Y() << "_" << time.M() << "_" << time.D(); 1912 2186 1913 groupName << fNightlyFile Name<< '/' << sTime.str() << ".fits";2187 groupName << fNightlyFilePath << '/' << sTime.str() << ".fits"; 1914 2188 } 1915 2189 CCfits::Table* groupTable; … … 1933 2207 1934 2208 groupTable = groupFile->addTable("GROUPING", numFilesToGroup, names, dataTypes); 2209 //TODO handle the case when the logger was stopped and restarted during the same day, i.e. the grouping file must be updated 1935 2210 } 1936 2211 catch (CCfits::FitsException e) … … 1952 2227 char* startOfLocation = reinterpret_cast<char*>(&fitsBuffer[8 + 3]); 1953 2228 char* startOfName = reinterpret_cast<char*>(&fitsBuffer[8+3+maxCharLength]); 1954 // char* startOfNameVisible = reinterpret_cast<char*>(&fitsBuffer[8 + 3 + 2*maxCharLength]); 2229 1955 2230 sprintf(startOfExtension, "%s", "BINTABLE"); 1956 2231 sprintf(startOfURI, "%s", "URL"); … … 1967 2242 Debug(str.str()); 1968 2243 } 1969 // strcpy(startOfNameVisible, jt->c_str());1970 2244 int status = 0; 1971 2245 fits_write_tblbytes(groupFile->fitsPointer(), i, 1, 8+3+2*maxCharLength, fitsBuffer, &status); … … 1982 2256 } 1983 2257 #endif //HAVE_FITS 2258 1984 2259 // -------------------------------------------------------------------------- 1985 2260 // … … 1995 2270 Debug("Stopping Run Logging..."); 1996 2271 } 1997 if (!fRunLogFile.is_open() || !fRunReportFile.is_open()) 1998 return kSM_FatalError; 1999 if (fRunLogFile.is_open()) 2000 fRunLogFile.close(); 2001 if (fRunReportFile.is_open()) 2002 fRunReportFile.close(); 2272 for (list<RunNumberType>::iterator it=fRunNumber.begin(); it != fRunNumber.end(); it++) 2273 { 2274 if (!it->logFile->is_open() || !it->reportFile->is_open()) 2275 return kSM_FatalError; 2276 it->logFile->close(); 2277 it->reportFile->close(); 2278 } 2279 2003 2280 #ifdef HAVE_FITS 2004 2281 for (SubscriptionsListType::iterator i = fServiceSubscriptions.begin(); i != fServiceSubscriptions.end(); i++) … … 2008 2285 j->second.runFile.Close(); 2009 2286 } 2010 if (fRunFitsFile != NULL)2011 {2012 delete fRunFitsFile;2013 fRunFitsFile = NULL;2014 (fNumSubAndFitsData.numOpenFits)--;2015 }2016 2287 #endif 2017 2288 NotifyOpenedFile("", 0, fOpenedRunFiles); … … 2019 2290 fNumSubAndFits->updateService(); 2020 2291 2021 CreateFitsGrouping(true); 2292 while (fRunNumber.size() > 0) 2293 { 2294 RemoveOldestRunNumber(); 2295 } 2022 2296 2023 2297 return kSM_WaitingRun; 2024 2025 2298 } 2026 2299 // -------------------------------------------------------------------------- … … 2032 2305 int DataLogger::GoToReadyPlease() 2033 2306 { 2034 2307 if (fDebugIsOn) 2035 2308 { 2036 2309 Debug("Going to the Ready state..."); 2037 2310 } 2311 if (GetCurrentState() == kSM_Logging) 2312 StopRunPlease(); 2313 2038 2314 if (fNightlyLogFile.is_open()) 2039 2315 fNightlyLogFile.close(); 2040 2316 if (fNightlyReportFile.is_open()) 2041 2317 fNightlyReportFile.close(); 2042 2043 if (fRunLogFile.is_open())2044 fRunLogFile.close();2045 if (fRunReportFile.is_open())2046 fRunReportFile.close();2047 2318 2048 2319 #ifdef HAVE_FITS … … 2051 2322 { 2052 2323 if (j->second.nightlyFile.IsOpen()) 2053 j->second.nightlyFile.Close(); 2054 if (j->second.runFile.IsOpen()) 2055 j->second.runFile.Close(); 2056 } 2057 if (fRunFitsFile != NULL) 2058 { 2059 delete fRunFitsFile; 2060 fRunFitsFile = NULL; 2061 (fNumSubAndFitsData.numOpenFits)--; 2062 } 2324 j->second.nightlyFile.Close();; 2325 } 2063 2326 #endif 2064 if (GetCurrentState() == kSM_Logging)2065 NotifyOpenedFile("", 0, fOpenedRunFiles);2066 2327 if (GetCurrentState() == kSM_Logging || 2067 2328 GetCurrentState() == kSM_WaitingRun || … … 2072 2333 fNumSubAndFits->updateService(); 2073 2334 } 2074 CreateFitsGrouping(true); 2075 CreateFitsGrouping(f alse);2076 2335 #ifdef HAVE_FITS 2336 CreateFitsGrouping(fOpenedNightlyFits, -1); 2337 #endif 2077 2338 return kSM_Ready; 2078 2339 } … … 2091 2352 return kSM_WaitingRun; 2092 2353 } 2093 2354 // -------------------------------------------------------------------------- 2355 // 2356 //! Setup Logger's configuration from a Configuration object 2357 //! @param conf the configuration object that should be used 2358 //! 2094 2359 bool DataLogger::SetConfiguration(Configuration& conf) 2095 2360 { … … 2149 2414 2150 2415 // -------------------------------------------------------------------------- 2151 2152 2416 int RunDim(Configuration &conf) 2153 2417 { … … 2169 2433 return 0; 2170 2434 } 2171 2435 // -------------------------------------------------------------------------- 2172 2436 void RunThread(DataLogger* logger) 2173 2437 { … … 2177 2441 Readline::Stop(); 2178 2442 } 2179 2443 // -------------------------------------------------------------------------- 2180 2444 template<class T> 2181 2445 int RunShell(Configuration &conf) … … 2235 2499 2236 2500 } 2237 2501 // -------------------------------------------------------------------------- 2238 2502 void PrintHelp() 2239 2503 { … … 2268 2532 cout << endl; 2269 2533 } 2270 2534 // -------------------------------------------------------------------------- 2271 2535 void SetupConfiguration(Configuration &conf) 2272 2536 { … … 2293 2557 conf.AddOptions(configs); 2294 2558 } 2295 2559 // -------------------------------------------------------------------------- 2296 2560 int main(int argc, const char* argv[]) 2297 2561 {
Note:
See TracChangeset
for help on using the changeset viewer.