2424#include " Common/DataModel/FT0Corrected.h"
2525#include " Common/DataModel/PIDResponseTOF.h"
2626
27+ #include < DataFormatsFIT/Triggers.h>
2728#include < CCDB/BasicCCDBManager.h>
2829#include < DataFormatsParameters/GRPLHCIFData.h>
2930#include < DataFormatsTOF/ParameterContainers.h>
@@ -536,6 +537,7 @@ struct tofEventTime {
536537 Produces<o2::aod::TOFEvTime> tableEvTime;
537538 Produces<o2::aod::EvTimeTOFOnly> tableEvTimeTOFOnly;
538539 Produces<o2::aod::pidEvTimeFlags> tableFlags;
540+ Produces<o2::aod::FT0sCorrected> tableFt0;
539541 static constexpr bool kRemoveTOFEvTimeBias = true ; // Flag to subtract the Ev. Time bias for low multiplicity events with TOF
540542 static constexpr float kDiamond = 6.0 ; // Collision diamond used in the estimation of the TOF event time
541543 static constexpr float kErrDiamond = kDiamond * 33 .356409f ;
@@ -658,14 +660,42 @@ struct tofEventTime {
658660 using ResponseImplementationEvTime = o2::pid::tof::ExpTimes<Run3TrksWtof::iterator, pid>;
659661 void processRun3 (Run3TrksWtof const & tracks,
660662 aod::FT0s const &,
661- EvTimeCollisionsFT0 const &,
663+ EvTimeCollisions const & collisions ,
662664 aod::BCsWithTimestamps const & bcs)
663665 {
664666 if (!enableTableTOFEvTime) {
665667 return ;
666668 }
667669 LOG (debug) << " Processing Run3 data for TOF event time" ;
668670
671+ std::map<uint64_t , std::pair<float , float >> collisionFt0Map;
672+ tableFt0.reserve (collisions.size ());
673+ for (const auto & collision : collisions) {
674+ static constexpr float DefaultValue = 1e10f;
675+ float t0A = DefaultValue;
676+ float t0C = DefaultValue;
677+ const float vertexPV = collision.posZ ();
678+ static constexpr float kInvLightSpeedCm2NS = 1 .f / o2::constants::physics::LightSpeedCm2NS;
679+ const float vertexCorr = vertexPV * kInvLightSpeedCm2NS ;
680+ constexpr float DummyTime = 30 .f ; // Due to HW limitations time can be only within range (-25,25) ns, dummy time is around 32 ns
681+ if (collision.has_foundFT0 ()) {
682+ const auto & ft0 = collision.foundFT0 ();
683+ const std::bitset<8 >& triggers = ft0.triggerMask ();
684+ const bool ora = triggers[o2::fit::Triggers::bitA];
685+ const bool orc = triggers[o2::fit::Triggers::bitC];
686+ LOGF (debug, " triggers OrA %i OrC %i " , ora, orc);
687+ LOGF (debug, " T0A = %f, T0C %f, vertexCorr %f" , ft0.timeA (), ft0.timeC (), vertexCorr);
688+ if (ora && ft0.timeA () < DummyTime) {
689+ t0A = ft0.timeA () + vertexCorr;
690+ }
691+ if (orc && ft0.timeC () < DummyTime) {
692+ t0C = ft0.timeC () - vertexCorr;
693+ }
694+ }
695+ LOGF (debug, " T0 collision time T0A = %f, T0C = %f" , t0A, t0C);
696+ tableFt0 (t0A, t0C);
697+ collisionFt0Map[collision.globalIndex ()] = std::make_pair (t0A, t0C); // Store the T0A and T0C for the collision
698+ }
669699 tableEvTime.reserve (tracks.size ());
670700 tableFlags.reserve (tracks.size ());
671701 if (enableTableEvTimeTOFOnly) {
@@ -692,7 +722,8 @@ struct tofEventTime {
692722 }
693723 LOG (debug) << " Running on " << CollisionSystemType::getCollisionSystemName (mTOFCalibConfig .collisionSystem ()) << " mComputeEvTimeWithTOF " << mComputeEvTimeWithTOF .value << " mComputeEvTimeWithFT0 " << mComputeEvTimeWithFT0 .value ;
694724
695- if (mComputeEvTimeWithTOF == 1 && mComputeEvTimeWithFT0 == 1 ) {
725+ if (mComputeEvTimeWithTOF == 1 && mComputeEvTimeWithFT0 == 1 ) { // Use both FT0 and TOF event times
726+
696727 int lastCollisionId = -1 ; // Last collision ID analysed
697728 for (auto const & t : tracks) { // Loop on collisions
698729 if (!t.has_collision () || ((sel8TOFEvTime.value == true ) && !t.collision_as <EvTimeCollisionsFT0>().sel8 ())) { // Track was not assigned, cannot compute event time or event did not pass the event selection
@@ -710,7 +741,7 @@ struct tofEventTime {
710741 lastCollisionId = t.collisionId (); // / Cache last collision ID
711742
712743 const auto & tracksInCollision = tracks.sliceBy (perCollision, lastCollisionId);
713- const auto & collision = t.collision_as <EvTimeCollisionsFT0 >();
744+ // const auto& collision = t.collision_as<EvTimeCollisions >();
714745
715746 // Compute the TOF event time
716747 const auto evTimeMakerTOF = evTimeMakerForTracks<Run3TrksWtof::iterator, filterForTOFEventTime, o2::pid::tof::ExpTimes>(tracksInCollision, mRespParamsV3 , kDiamond );
@@ -743,13 +774,14 @@ struct tofEventTime {
743774 sumOfWeights += weight;
744775 }
745776
746- if (collision.has_foundFT0 ()) { // T0 measurement is available
747- // const auto& ft0 = collision.foundFT0();
748- if (collision.t0ACValid ()) {
749- t0AC[0 ] = collision.t0AC () * 1000 .f ;
750- t0AC[1 ] = collision.t0resolution () * 1000 .f ;
751- flags |= o2::aod::pidflags::enums::PIDFlags::EvTimeT0AC;
752- }
777+ float t0A = collisionFt0Map[t.collisionId ()].first ; // T0A for the collision
778+ float t0C = collisionFt0Map[t.collisionId ()].second ; // T0C for the collision
779+
780+ static constexpr float ThresholdValue = 1e9f; // I the value of the FT0s are defined, the values are lower than 10e9
781+ if ((t0A < ThresholdValue) && (t0C < ThresholdValue)) {
782+ t0AC[0 ] = 0.5 * (t0A + t0C) * 1000 .f ;
783+ t0AC[1 ] = 0.5 * std::abs (t0A - t0C) * 1000 .f ;
784+ flags |= o2::aod::pidflags::enums::PIDFlags::EvTimeT0AC;
753785
754786 weight = 1 .f / (t0AC[1 ] * t0AC[1 ]);
755787 eventTime += t0AC[0 ] * weight;
@@ -769,7 +801,8 @@ struct tofEventTime {
769801 }
770802 }
771803 }
772- } else if (mComputeEvTimeWithTOF == 1 && mComputeEvTimeWithFT0 == 0 ) {
804+ } else if (mComputeEvTimeWithTOF == 1 && mComputeEvTimeWithFT0 == 0 ) { // Use TOF event time only
805+
773806 int lastCollisionId = -1 ; // Last collision ID analysed
774807 for (auto const & t : tracks) { // Loop on collisions
775808 if (!t.has_collision () || ((sel8TOFEvTime.value == true ) && !t.collision_as <EvTimeCollisions>().sel8 ())) { // Track was not assigned, cannot compute event time or event did not pass the event selection
@@ -812,7 +845,8 @@ struct tofEventTime {
812845 }
813846 }
814847 }
815- } else if (mComputeEvTimeWithTOF == 0 && mComputeEvTimeWithFT0 == 1 ) {
848+ } else if (mComputeEvTimeWithTOF == 0 && mComputeEvTimeWithFT0 == 1 ) { // Use FT0 event time only
849+
816850 for (auto const & t : tracks) { // Loop on collisions
817851 if (enableTableEvTimeTOFOnly) {
818852 tableEvTimeTOFOnly ((uint8_t )0 , 0 .f , 0 .f , -1 );
@@ -822,20 +856,22 @@ struct tofEventTime {
822856 tableEvTime (0 .f , 999 .f );
823857 continue ;
824858 }
825- const auto & collision = t.collision_as <EvTimeCollisionsFT0>();
826-
827- if (collision.has_foundFT0 ()) { // T0 measurement is available
828- // const auto& ft0 = collision.foundFT0();
829- if (collision.t0ACValid ()) {
830- tableFlags (o2::aod::pidflags::enums::PIDFlags::EvTimeT0AC);
831- tableEvTime (collision.t0AC () * 1000 .f , collision.t0resolution () * 1000 .f );
832- continue ;
833- }
859+
860+ float t0A = collisionFt0Map[t.collisionId ()].first ; // T0A for the collision
861+ float t0C = collisionFt0Map[t.collisionId ()].second ; // T0C for the collision
862+
863+ static constexpr float ThresholdValue = 1e9f; // I the value of the FT0s are defined, the values are lower than 10e9
864+ float t0AC[2 ] = {.0f , 999 .f };
865+ uint8_t flags = 0 ;
866+ if ((t0A < ThresholdValue) && (t0C < ThresholdValue)) {
867+ t0AC[0 ] = 0.5 * (t0A + t0C) * 1000 .f ;
868+ t0AC[1 ] = 0.5 * std::abs (t0A - t0C) * 1000 .f ;
869+ flags = o2::aod::pidflags::enums::PIDFlags::EvTimeT0AC;
834870 }
835- tableFlags (0 );
836- tableEvTime (0 . f , 999 . f );
871+ tableFlags (flags );
872+ tableEvTime (t0AC[ 0 ], t0AC[ 1 ] );
837873 }
838- } else {
874+ } else { // Error
839875 LOG (fatal) << " Invalid configuration for TOF event time computation" ;
840876 }
841877 }
@@ -942,7 +978,7 @@ struct tofPidMerge {
942978 doprocessRun2.value = false ;
943979 } else {
944980 if (mTOFCalibConfig .autoSetProcessFunctions ()) {
945- LOG (info) << " Autodetecting process functions" ;
981+ LOG (info) << " Autodetecting process functions for mass and beta " ;
946982 if (metadataInfo.isFullyDefined ()) {
947983 if (metadataInfo.isRun3 ()) {
948984 doprocessRun3.value = true ;
0 commit comments