@@ -116,7 +116,8 @@ class CTFWriterSpec : public o2::framework::Task
116116 bool mCreateDict = false ;
117117 bool mDictPerDetector = false ;
118118 bool mCreateRunEnvDir = true ;
119- int mSaveDictAfter = -1 ; // if positive and mWriteCTF==true, save dictionary after each mSaveDictAfter TFs processed
119+ bool mStoreMetaFile = false ;
120+ int mSaveDictAfter = 0 ; // if positive and mWriteCTF==true, save dictionary after each mSaveDictAfter TFs processed
120121 uint64_t mRun = 0 ;
121122 size_t mMinSize = 0 ; // if > 0, accumulate CTFs in the same tree until the total size exceeds this minimum
122123 size_t mMaxSize = 0 ; // if > MinSize, and accumulated size will exceed this value, stop accumulation (even if mMinSize is not reached)
@@ -125,14 +126,17 @@ class CTFWriterSpec : public o2::framework::Task
125126 size_t mCurrCTFSize = 0 ; // size of currently processed CTF
126127 size_t mNCTF = 0 ; // total number of CTFs written
127128 size_t mNAccCTF = 0 ; // total number of CTFs accumulated in the current file
129+ size_t mCTFAutoSave = 0 ; // if > 0, autosave after so many TFs
128130 size_t mNCTFFiles = 0 ; // total number of CTF files written
131+ int mMaxCTFPerFile = 0 ; // max CTFs per files to store
129132 std::vector<uint32_t > mTFOrbits {}; // 1st orbits of TF accumulated in current file
130133
131134 std::string mLHCPeriod {};
132135 std::string mEnvironmentID {}; // partition env. id
133136 std::string mDictDir {};
134137 std::string mCTFDir {};
135138 std::string mCTFDirFallBack = " /dev/null" ;
139+ std::string mCTFMetaFileDir = " /dev/null" ;
136140 std::string mCurrentCTFFileName {};
137141 const std::string LOCKFileDir = " /tmp/ctf-writer-locks" ;
138142 std::string mLockFileName {};
@@ -185,15 +189,22 @@ CTFWriterSpec::CTFWriterSpec(DetID::mask_t dm, uint64_t r, bool doCTF, bool doDi
185189void CTFWriterSpec::init (InitContext& ic)
186190{
187191 mSaveDictAfter = ic.options ().get <int >(" save-dict-after" );
192+ mCTFAutoSave = ic.options ().get <int >(" save-ctf-after" );
188193 mDictDir = o2::utils::Str::rectifyDirectory (ic.options ().get <std::string>(" ctf-dict-dir" ));
189194 mCTFDir = o2::utils::Str::rectifyDirectory (ic.options ().get <std::string>(" output-dir" ));
190195 mCTFDirFallBack = ic.options ().get <std::string>(" output-dir-alt" );
191196 if (mCTFDirFallBack != " /dev/null" ) {
192197 mCTFDirFallBack = o2::utils::Str::rectifyDirectory (mCTFDirFallBack );
193198 }
199+ mCTFMetaFileDir = ic.options ().get <std::string>(" meta-output-dir" );
200+ if (mCTFMetaFileDir != " /dev/null" ) {
201+ mCTFMetaFileDir = o2::utils::Str::rectifyDirectory (" /dev/null" );
202+ mStoreMetaFile = true ;
203+ }
194204 mCreateRunEnvDir = !ic.options ().get <bool >(" ignore-partition-run-dir" );
195205 mMinSize = ic.options ().get <int64_t >(" min-file-size" );
196206 mMaxSize = ic.options ().get <int64_t >(" max-file-size" );
207+ mMaxCTFPerFile = ic.options ().get <int >(" max-ctf-per-file" );
197208 if (mWriteCTF ) {
198209 if (mMinSize > 0 ) {
199210 LOG (INFO) << " Multiple CTFs will be accumulated in the tree/file until its size exceeds " << mMinSize << " bytes" ;
@@ -386,14 +397,16 @@ void CTFWriterSpec::run(ProcessingContext& pc)
386397 lseek (mLockFD , 0 , SEEK_SET);
387398 write (mLockFD , &mAccCTFSize , sizeof (size_t ));
388399 }
400+
401+ if (mAccCTFSize >= mMinSize || (mMaxCTFPerFile > 0 && mNAccCTF >= mMaxCTFPerFile )) {
402+ closeTFTreeAndFile ();
403+ } else if (mCTFAutoSave > 0 && mNAccCTF % mCTFAutoSave == 0 ) {
404+ mCTFTreeOut ->AutoSave (" override" );
405+ }
389406 } else {
390407 LOG (INFO) << " TF#" << mNCTF << " CTF writing is disabled, size was " << szCTF << " bytes" ;
391408 }
392409
393- if (mWriteCTF && mAccCTFSize >= mMinSize ) {
394- closeTFTreeAndFile ();
395- }
396-
397410 mNCTF ++;
398411 if (mCreateDict && mSaveDictAfter > 0 && (mNCTF % mSaveDictAfter ) == 0 ) {
399412 storeDictionaries ();
@@ -457,7 +470,9 @@ void CTFWriterSpec::prepareTFTreeAndFile(const o2::header::DataHeader* dh)
457470 mCurrentCTFFileName = o2::utils::Str::concat_string (ctfDir, o2::base::NameConf::getCTFFileName (mRun , dh->firstTForbit , dh->tfCounter ));
458471 mCTFFileOut .reset (TFile::Open (o2::utils::Str::concat_string (mCurrentCTFFileName , TMPFileEnding).c_str (), " recreate" )); // to prevent premature external usage, use temporary name
459472 mCTFTreeOut = std::make_unique<TTree>(std::string (o2::base::NameConf::CTFTREENAME).c_str (), " O2 CTF tree" );
460- mCTFFileMetaData = std::make_unique<o2::dataformats::FileMetaData>();
473+ if (mStoreMetaFile ) {
474+ mCTFFileMetaData = std::make_unique<o2::dataformats::FileMetaData>();
475+ }
461476
462477 mNCTFFiles ++;
463478 }
@@ -474,26 +489,28 @@ void CTFWriterSpec::closeTFTreeAndFile()
474489 if (!TMPFileEnding.empty ()) {
475490 std::filesystem::rename (o2::utils::Str::concat_string (mCurrentCTFFileName , TMPFileEnding), mCurrentCTFFileName );
476491 }
477- // write CTF file meta data
478- mCTFFileMetaData ->fillFileData (mCurrentCTFFileName );
479- mCTFFileMetaData ->run = mRun ;
480- mCTFFileMetaData ->LHCPeriod = mLHCPeriod ;
481- mCTFFileMetaData ->type = " raw" ;
482- mCTFFileMetaData ->priority = " high" ;
483- auto metaName = o2::utils::Str::concat_string (mCurrentCTFFileName , " .done" );
484- try {
485- std::ofstream metaOut (metaName);
486- metaOut << *mCTFFileMetaData .get ();
487- metaOut << " TFOrbits: " ;
488- for (size_t i = 0 ; i < mTFOrbits .size (); i++) {
489- metaOut << fmt::format (" {}{}" , i ? " , " : " " , mTFOrbits [i]);
492+ // write CTF file metaFile data
493+ if (mStoreMetaFile ) {
494+ mCTFFileMetaData ->fillFileData (mCurrentCTFFileName );
495+ mCTFFileMetaData ->run = mRun ;
496+ mCTFFileMetaData ->LHCPeriod = mLHCPeriod ;
497+ mCTFFileMetaData ->type = " raw" ;
498+ mCTFFileMetaData ->priority = " high" ;
499+ auto metaFileName = o2::utils::Str::concat_string (mCurrentCTFFileName , " .done" );
500+ try {
501+ std::ofstream metaFileOut (metaFileName);
502+ metaFileOut << *mCTFFileMetaData .get ();
503+ metaFileOut << " TFOrbits: " ;
504+ for (size_t i = 0 ; i < mTFOrbits .size (); i++) {
505+ metaFileOut << fmt::format (" {}{}" , i ? " , " : " " , mTFOrbits [i]);
506+ }
507+ metaFileOut << ' \n ' ;
508+ metaFileOut.close ();
509+ } catch (std::exception const & e) {
510+ LOG (ERROR) << " Failed to store CTF meta data file " << metaFileName << " , reason: " << e.what ();
490511 }
491- metaOut << ' \n ' ;
492- metaOut.close ();
493- } catch (std::exception const & e) {
494- LOG (ERROR) << " Failed to store CTF metadata file " << metaName << " , reason: " << e.what ();
512+ mCTFFileMetaData .reset ();
495513 }
496- mCTFFileMetaData .reset ();
497514 mTFOrbits .clear ();
498515 mNAccCTF = 0 ;
499516 mAccCTFSize = 0 ;
@@ -668,12 +685,15 @@ DataProcessorSpec getCTFWriterSpec(DetID::mask_t dets, uint64_t run, bool doCTF,
668685 inputs,
669686 Outputs{},
670687 AlgorithmSpec{adaptFromTask<CTFWriterSpec>(dets, run, doCTF, doDict, dictPerDet)},
671- Options{{" save-dict-after" , VariantType::Int, - 1 , {" In dictionary generation mode save it dictionary after certain number of TFs processed" }},
688+ Options{{" save-dict-after" , VariantType::Int, 0 , {" if > 0, in dictionary generation mode save it dictionary after certain number of TFs processed" }},
672689 {" ctf-dict-dir" , VariantType::String, " none" , {" CTF dictionary directory, must exist" }},
673690 {" output-dir" , VariantType::String, " none" , {" CTF output directory, must exist" }},
674691 {" output-dir-alt" , VariantType::String, " /dev/null" , {" Alternative CTF output directory, must exist (if not /dev/null)" }},
692+ {" meta-output-dir" , VariantType::String, " /dev/null" , {" CTF metadata output directory, must exist (if not /dev/null)" }},
675693 {" min-file-size" , VariantType::Int64, 0l , {" accumulate CTFs until given file size reached" }},
676694 {" max-file-size" , VariantType::Int64, 0l , {" if > 0, try to avoid exceeding given file size, also used for space check" }},
695+ {" max-ctf-per-file" , VariantType::Int, 0 , {" if > 0, avoid storing more than requested CTFs per file" }},
696+ {" save-ctf-after" , VariantType::Int, 0 , {" if > 0, autosave CTF tree with multiple CTFs after every N CTFs" }},
677697 {" ignore-partition-run-dir" , VariantType::Bool, false , {" Do not creare partition-run directory in output-dir" }}}};
678698}
679699
0 commit comments